Merge pull request #1325 from SteveGilvarry/feature-h264-videostorage

Merge Master to feature-h264-videostorage
This commit is contained in:
Steve Gilvarry 2016-03-09 21:16:13 +11:00
commit 5f6d47fee8
551 changed files with 33633 additions and 45742 deletions

View File

@ -352,7 +352,7 @@
- Fix window sizes and input field sizes for flat skin [\#381](https://github.com/ZoneMinder/ZoneMinder/pull/381) ([m-bene](https://github.com/m-bene)) - Fix window sizes and input field sizes for flat skin [\#381](https://github.com/ZoneMinder/ZoneMinder/pull/381) ([m-bene](https://github.com/m-bene))
- Fix reload loop on switching skins [\#380](https://github.com/ZoneMinder/ZoneMinder/pull/380) ([m-bene](https://github.com/m-bene)) - Fix reload loop on switching skins [\#380](https://github.com/ZoneMinder/ZoneMinder/pull/380) ([m-bene](https://github.com/m-bene))
- Ability to skip frames in motion detection. [\#377](https://github.com/ZoneMinder/ZoneMinder/pull/377) ([Sune1337](https://github.com/Sune1337)) - Ability to skip frames in motion detection. [\#377](https://github.com/ZoneMinder/ZoneMinder/pull/377) ([Sune1337](https://github.com/Sune1337))
- same dvr controlls in event as in monitor [\#375](https://github.com/ZoneMinder/ZoneMinder/pull/375) ([m-bene](https://github.com/m-bene)) - same dvr controls in event as in monitor [\#375](https://github.com/ZoneMinder/ZoneMinder/pull/375) ([m-bene](https://github.com/m-bene))
- do not quote column names in parse filter [\#374](https://github.com/ZoneMinder/ZoneMinder/pull/374) ([m-bene](https://github.com/m-bene)) - do not quote column names in parse filter [\#374](https://github.com/ZoneMinder/ZoneMinder/pull/374) ([m-bene](https://github.com/m-bene))
- Fix 'Undefined index: filter' php warnings for filter view when [\#373](https://github.com/ZoneMinder/ZoneMinder/pull/373) ([m-bene](https://github.com/m-bene)) - Fix 'Undefined index: filter' php warnings for filter view when [\#373](https://github.com/ZoneMinder/ZoneMinder/pull/373) ([m-bene](https://github.com/m-bene))
- Reduce window size to exclude task bar area [\#371](https://github.com/ZoneMinder/ZoneMinder/pull/371) ([m-bene](https://github.com/m-bene)) - Reduce window size to exclude task bar area [\#371](https://github.com/ZoneMinder/ZoneMinder/pull/371) ([m-bene](https://github.com/m-bene))

View File

@ -133,9 +133,9 @@ set(ZM_NO_CURL "OFF" CACHE BOOL
"Set to ON to skip cURL checks and force building ZM without cURL. default: OFF") "Set to ON to skip cURL checks and force building ZM without cURL. default: OFF")
set(ZM_NO_X10 "OFF" CACHE BOOL set(ZM_NO_X10 "OFF" CACHE BOOL
"Set to ON to build ZoneMinder without X10 support. default: OFF") "Set to ON to build ZoneMinder without X10 support. default: OFF")
set(ZM_ONVIF "OFF" CACHE BOOL set(ZM_ONVIF "ON" CACHE BOOL
"Set to ON to enable basic ONVIF support. This is EXPERIMENTAL and may not "Set to ON to enable basic ONVIF support. This is EXPERIMENTAL and may not
work with all cameras claiming to be ONVIF compliant. default: OFF") work with all cameras claiming to be ONVIF compliant. default: ON")
set(ZM_PERL_MM_PARMS INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 CACHE STRING set(ZM_PERL_MM_PARMS INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 CACHE STRING
"By default, ZoneMinder's Perl modules are installed into the Vendor folders, "By default, ZoneMinder's Perl modules are installed into the Vendor folders,
as defined by your installation of Perl. You can change that here. Consult Perl's as defined by your installation of Perl. You can change that here. Consult Perl's

View File

@ -1,6 +1,6 @@
# ZoneMinder # ZoneMinder
FROM ubuntu:precise FROM ubuntu:trusty
MAINTAINER Kyle Johnson <kjohnson@gnulnx.net> MAINTAINER Kyle Johnson <kjohnson@gnulnx.net>
# Let the container know that there is no tty # Let the container know that there is no tty
@ -10,10 +10,10 @@ ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
libpolkit-gobject-1-dev build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev \ libpolkit-gobject-1-dev build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev \
libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 \ libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 \
libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm automake autoconf libjpeg-turbo8-dev \ libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm cmake libjpeg-turbo8-dev \
libjpeg-turbo8 libtheora-dev libvorbis-dev libvpx-dev libx264-dev libmp4v2-dev libav-tools mysql-client \ libjpeg-turbo8 libtheora-dev libvorbis-dev libvpx-dev libx264-dev libmp4v2-dev libav-tools mysql-client \
apache2 php5 php5-mysql apache2-mpm-prefork libapache2-mod-php5 php5-cli openssh-server \ apache2 php5 php5-mysql apache2-mpm-prefork libapache2-mod-php5 php5-cli openssh-server \
mysql-server libvlc-dev libvlc5 libvlccore-dev libvlccore5 vlc-data libcurl4-openssl-dev \ mysql-server libvlc-dev libvlc5 libvlccore-dev libvlccore7 vlc-data libcurl4-openssl-dev \
libavformat-dev libswscale-dev libavutil-dev libavcodec-dev libavfilter-dev \ libavformat-dev libswscale-dev libavutil-dev libavcodec-dev libavfilter-dev \
libavresample-dev libavdevice-dev libpostproc-dev libv4l-dev libtool libnetpbm10-dev \ libavresample-dev libavdevice-dev libpostproc-dev libv4l-dev libtool libnetpbm10-dev \
libmime-lite-perl dh-autoreconf dpatch libmime-lite-perl dh-autoreconf dpatch
@ -25,10 +25,11 @@ ADD . /ZoneMinder
WORKDIR /ZoneMinder WORKDIR /ZoneMinder
# Setup the ZoneMinder build environment # Setup the ZoneMinder build environment
RUN aclocal && autoheader && automake --force-missing --add-missing && autoconf #RUN aclocal && autoheader && automake --force-missing --add-missing && autoconf
# Configure ZoneMinder # Configure ZoneMinder
RUN ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-webdir=/var/www/zm --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-mmap=yes ZM_SSL_LIB=openssl ZM_DB_USER=zm ZM_DB_PASS=zm #RUN ./configure --with-libarch=lib/$DEB_HOST_GNU_TYPE --disable-debug --host=$DEB_HOST_GNU_TYPE --build=$DEB_BUILD_GNU_TYPE --with-mysql=/usr --with-webdir=/var/www/zm --with-ffmpeg=/usr --with-cgidir=/usr/lib/cgi-bin --with-webuser=www-data --with-webgroup=www-data --enable-mmap=yes --enable-onvif ZM_SSL_LIB=openssl ZM_DB_USER=zm ZM_DB_PASS=zm
RUN cmake .
# Build ZoneMinder # Build ZoneMinder
RUN make RUN make
@ -36,6 +37,9 @@ RUN make
# Install ZoneMinder # Install ZoneMinder
RUN make install RUN make install
# ensure writable folders
RUN ./zmlinkcontent.sh
# Adding the start script # Adding the start script
ADD utils/docker/start.sh /tmp/start.sh ADD utils/docker/start.sh /tmp/start.sh
@ -43,15 +47,23 @@ ADD utils/docker/start.sh /tmp/start.sh
# TODO - Files ADD'ed have 755 already...why do we need this? # TODO - Files ADD'ed have 755 already...why do we need this?
RUN chmod 755 /tmp/start.sh RUN chmod 755 /tmp/start.sh
# Creating SSH privledge escalation dir # give files in /usr/local/share/zoneminder/
RUN chown -R www-data:www-data /usr/local/share/zoneminder/
# Creating SSH privilege escalation dir
RUN mkdir /var/run/sshd RUN mkdir /var/run/sshd
# Adding apache virtual hosts file # Adding apache virtual hosts file
ADD utils/docker/apache-vhost /etc/apache2/sites-enabled/000-default ADD utils/docker/apache-vhost /etc/apache2/sites-available/000-default.conf
ADD utils/docker/phpdate.ini /etc/php5/apache2/conf.d/25-phpdate.ini
# Set the root passwd # Set the root passwd
RUN echo 'root:root' | chpasswd RUN echo 'root:root' | chpasswd
# Add a user we can actually login with
RUN useradd -m -s /bin/bash -G sudo zoneminder
RUN echo 'zoneminder:zoneminder' | chpasswd
# Expose ssh and http ports # Expose ssh and http ports
EXPOSE 80 EXPOSE 80
EXPOSE 22 EXPOSE 22

View File

@ -18,7 +18,7 @@ Important differences
--------------------- ---------------------
* Unlike the autotools way, the cmake way does not require any options. It attempts to detect some things by its own (system directories, libarch, web user and group) and uses defaults for others (installation paths and such). * Unlike the autotools way, the cmake way does not require any options. It attempts to detect some things by its own (system directories, libarch, web user and group) and uses defaults for others (installation paths and such).
* Unlike the autotools way, which links the binaries to a fixed list of libraries, the cmake way only links to libraries that it found on the system. If a library is not found, but required, a fatal error will be shown during the configuration step. * Unlike the autotools way, which links the binaries to a fixed list of libraries, the cmake way only links to libraries that it found on the system. If a library is not found, but required, a fatal error will be shown during the configuration step.
* Unlike the autotools way, the cmake way does not modify the system in any way it shouldnt. It only does what its supposed to do: Install files to your system. Nothing else and nothing leaks out of the DESTDIR environment variable (if used). This means that depending on your configuration, there might be an extra required step after installation: to link WEB_PATH/events and WEB_PATH/images folders to the correct places. * Unlike the autotools way, the cmake way does not modify the system in any way it shouldn't. It only does what its supposed to do: Install files to your system. Nothing else and nothing leaks out of the DESTDIR environment variable (if used). This means that depending on your configuration, there might be an extra required step after installation: to link WEB_PATH/events and WEB_PATH/images folders to the correct places.
Configuration Configuration
------------- -------------

View File

@ -239,7 +239,7 @@ Now clone the ZoneMinder git repository:
```bash ```bash
git clone https://github.com/ZoneMinder/ZoneMinder git clone https://github.com/ZoneMinder/ZoneMinder
``` ```
This will create a sub-folder called ZoneMinder, which will contain the latest developement. This will create a sub-folder called ZoneMinder, which will contain the latest development.
We want to turn this into a tarball, but first we need to figure out what to name it. Look here: We want to turn this into a tarball, but first we need to figure out what to name it. Look here:
```bash ```bash

View File

@ -590,8 +590,10 @@ INSERT INTO Controls VALUES (NULL,'ONVIF Camera','Ffmpeg','onvif',0,0,1,1,0,0,0,
INSERT INTO `Controls` VALUES (NULL,'Foscam 9831W','Ffmpeg','FI9831W',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,1,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,0,0,0,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Foscam 9831W','Ffmpeg','FI9831W',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,16,1,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,0,0,0,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'Foscam FI8918W','Ffmpeg','FI8918W',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,1,0,0,0,1,1,0,360,0,360,1,0,4,0,0,1,0,90,0,90,1,0,4,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0); INSERT INTO `Controls` VALUES (NULL,'SunEyes SP-P1802SWPTZ','Libvlc','SPP1802SWPTZ',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,8,0,1,1,0,0,0,0,1,1,0,0,0,0,1,0,64,0,0,1,0,0,0,0,1,0,64,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'Wanscam HW0025','Libvlc','WanscamHW0025', 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0);
INSERT INTO `Controls` VALUES (NULL,'IPCC 7210W','Libvlc','IPCC7210W', 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 350, 0, 0, 1, 0, 10, 0, 0, 1, 0, 0, 0, 0, 1, 0, 10, 0, 0, 0, 0);
INSERT INTO `Controls` VALUES (NULL,'Vivotek ePTZ','Remote','Vivotek_ePTZ',0,0,1,1,0,0,0,1,0,0,0,0,1,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,1,0,5,0,0,1,0,0,0,0,1,0,5,0,0,0,0);
INSERT INTO `Controls` VALUES (NULL,'Netcat ONVIF','Ffmpeg','Netcat',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,100,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,100,5,5,0,0,0,1,255,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
-- --
-- Add some monitor preset values -- Add some monitor preset values

View File

@ -1,5 +1,5 @@
-- --
-- This updates a 1.28.106 database to 1.28.107 -- This updates a 1.28.108 database to 1.28.109
-- --
-- --

View File

@ -1,5 +1,5 @@
-- --
-- This updates a 1.28.106 database to 1.28.107 -- This updates a 1.28.109 database to 1.28.110
-- --
-- --

View File

@ -10,7 +10,7 @@ configure_file(zoneminder.tmpfiles.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.tmp
configure_file(zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY) configure_file(zoneminder.logrotate.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.logrotate @ONLY)
# Download jscalendar & move files into position # Download jscalendar & move files into position
file(DOWNLOAD http://downloads.sourceforge.net/jscalendar/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip STATUS download_jsc) file(DOWNLOAD http://iweb.dl.sourceforge.net/project/jscalendar/jscalendar/1.0/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip STATUS download_jsc)
if(download_jsc EQUAL 0) if(download_jsc EQUAL 0)
message(STATUS "Jscalander successfully downloaded. Installing...") message(STATUS "Jscalander successfully downloaded. Installing...")
execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc) execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ERROR_VARIABLE unzip_jsc)
@ -39,7 +39,7 @@ install(CODE "execute_process(COMMAND ln -sf ../../../../../../var/lib/zoneminde
# Fedora requires cambozola as a separate package so just link to it # Fedora requires cambozola as a separate package so just link to it
install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")") install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")")
# Install auxillary files required to run zoneminder on Fedora # Install auxiliary files required to run zoneminder on Fedora
install(FILES zoneminder.conf DESTINATION /etc/httpd/conf.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES zoneminder.conf DESTINATION /etc/httpd/conf.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES ../../misc/zoneminder-tmpfiles.conf DESTINATION /etc/tmpfiles.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES ../../misc/zoneminder-tmpfiles.conf DESTINATION /etc/tmpfiles.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

View File

@ -5,27 +5,19 @@ What's New
"/cgi-bin-zm/zms". This has been to done to avoid this bug: "/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067 https://bugzilla.redhat.com/show_bug.cgi?id=973067
IMPORTANT: ZoneMinder will not update this value during an upgrade. You must IMPORTANT: You must manually inspect the value for PATH_ZMS under Options
manually update ZM_PATH_ZMS yourself under Options. This does not affect and verify it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
new installs. in a broken system. You have been warned.
2. The ZoneMinder config file, zm.conf, has been moved under /etc/zm. 2. Due to the active state of the ZoneMinder project, we now recommend granting
3. Due to the active state of the ZoneMinder project, we now recommend granting
ALL permission to the ZoneMinder mysql account. This change must be done ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below. manually before ZoneMinder will run. See the installation steps below.
4. A new permission group called "Groups" has been added. This allows the 3. This package uses the HTTPS protocol by default to access the web portal.
system administrator to assign "view", "edit", or "none" permission to
normal users, without giving them access to the rest of the ZoneMinder
system. During an upgrade, existing accounts will default to a Groups
permission of "none".
5. This package now requires the HTTPS protocol to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
6. This package ships with the new ZoneMinder API enabled. 4. This package ships with the new ZoneMinder API enabled.
New installs New installs
============ ============
@ -86,13 +78,22 @@ New installs
SELINUX line from "enforcing" to "disabled". This change will take SELINUX line from "enforcing" to "disabled". This change will take
effect after a reboot. effect after a reboot.
6. Install mod_ssl or configure /etc/httpd/conf.d/zoneminder.conf to meet your
needs. This package comes preconfigured for HTTPS using the default self
signed certificate on your system. The recommended way to complete this step
is to simply install mod_ssl:
6. Now start the web server: sudo yum install mod_ssl
If this does not meet your needs, then read README.https to
learn about alternatives. When in doubt, install mod_ssl.
7. Now start the web server:
sudo systemctl enable httpd sudo systemctl enable httpd
sudo systemctl start httpd sudo systemctl start httpd
7. Now start zoneminder: 8. Now start zoneminder:
sudo systemctl enable zoneminder sudo systemctl enable zoneminder
sudo systemctl start zoneminder sudo systemctl start zoneminder
@ -131,6 +132,7 @@ Upgrades
/etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there /etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there
may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file
exists, inspect it and merge anything new in that file with zoneminder.conf. exists, inspect it and merge anything new in that file with zoneminder.conf.
Verify the SSL REquirements meet your needs. Read README.https if necessary.
4. Upgrade the database before starting ZoneMinder. 4. Upgrade the database before starting ZoneMinder.

View File

@ -0,0 +1 @@
zoneminder.f23.spec

View File

@ -1,409 +0,0 @@
%define zmuid $(id -un)
%define zmgid $(id -gn)
%define zmuid_final apache
%define zmgid_final apache
%global _hardened_build 1
### Delete the lines below to build with ffmpeg and/or x10
%define _without_ffmpeg 1
%define _without_x10 1
Name: zoneminder
Version: 1.29.0
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons
# jscalendar is LGPL (any version): http://www.dynarch.com/projects/calendar/
# Mootools is inder the MIT license: http://mootools.net/
License: GPLv2+ and LGPLv2+ and MIT
URL: http://www.zoneminder.com/
#Source: https://github.com/ZoneMinder/ZoneMinder/archive/v%{version}.tar.gz
Source: ZoneMinder-%{version}.tar.gz
BuildRequires: cmake gnutls-devel systemd-units bzip2-devel
BuildRequires: mariadb-devel pcre-devel libjpeg-turbo-devel
BuildRequires: perl(Archive::Tar) perl(Archive::Zip) perl-podlators
BuildRequires: perl(Date::Manip) perl(DBD::mysql)
BuildRequires: perl(ExtUtils::MakeMaker) perl(LWP::UserAgent)
BuildRequires: perl(MIME::Entity) perl(MIME::Lite)
BuildRequires: perl(PHP::Serialization) perl(Sys::Mmap)
BuildRequires: perl(Time::HiRes) perl(Net::SFTP::Foreign)
BuildRequires: perl(Expect) perl(Sys::Syslog)
BuildRequires: gcc gcc-c++ vlc-devel libcurl-devel libv4l-devel
%{!?_without_ffmpeg:BuildRequires: ffmpeg-devel}
%{!?_without_x10:BuildRequires: perl(X10::ActiveHome) perl(Astro::SunTime)}
# cmake needs the following installed at build time due to the way it auto-detects certain parameters
BuildRequires: httpd polkit-devel
%{!?_without_ffmpeg:BuildRequires: ffmpeg}
Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc
Requires: libjpeg-turbo vlc-core libcurl
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP)
Requires: perl(LWP::Protocol::https)
%{!?_without_ffmpeg:Requires: ffmpeg}
Requires(post): systemd-units systemd-sysv
Requires(post): /usr/bin/gpasswd
Requires(post): /usr/bin/less
Requires(preun): systemd-units
Requires(postun): systemd-units
%description
ZoneMinder is a set of applications which is intended to provide a complete
solution allowing you to capture, analyse, record and monitor any cameras you
have attached to a Linux based machine. It is designed to run on kernels which
support the Video For Linux (V4L) interface and has been tested with cameras
attached to BTTV cards, various USB cameras and IP network cameras. It is
designed to support as many cameras as you can attach to your computer without
too much degradation of performance.
%prep
%setup -q -n ZoneMinder-%{version}
# Change the following default values
./utils/zmeditconfigdata.sh ZM_PATH_ZMS /cgi-bin-zm/nph-zms
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
./utils/zmeditconfigdata.sh ZM_PATH_SWAP /dev/shm
./utils/zmeditconfigdata.sh ZM_UPLOAD_FTP_LOC_DIR /var/spool/zoneminder-upload
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
%build
%cmake \
-DZM_TARGET_DISTRO="f22" \
%{?_without_ffmpeg:-DZM_NO_FFMPEG=ON} \
%{?_without_x10:-DZM_NO_X10=ON} \
.
make %{?_smp_mflags}
%install
export DESTDIR=%{buildroot}
make install
%post
if [ $1 -eq 1 ] ; then
# Initial installation
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
fi
# Allow zoneminder access to local video sources, serial ports, and x10
/usr/bin/gpasswd -a %{zmuid_final} video
/usr/bin/gpasswd -a %{zmuid_final} dialout
# Upgrade from a previous version of zoneminder
if [ $1 -eq 2 ] ; then
# Freshen the database
/usr/bin/zmupdate.pl -f
# We can't run this automatically when new sql account permissions need to
# be manually added first
# Run zmupdate non-interactively
#/usr/bin/zmupdate.pl --nointeractive
fi
# Warn the end user to read the README file
echo -e "\nVERY IMPORTANT: Before starting ZoneMinder, read README.Fedora to finish the\ninstallation or upgrade!\n"
echo -e "\nThe README file is located here: %{_docdir}/%{name}\n"
%preun
if [ $1 -eq 0 ] ; then
# Package removal, not upgrade
/bin/systemctl --no-reload disable zoneminder.service > /dev/null 2>&1 || :
/bin/systemctl stop zoneminder.service > /dev/null 2>&1 || :
fi
%postun
/bin/systemctl daemon-reload >/dev/null 2>&1 || :
if [ $1 -ge 1 ] ; then
# Package upgrade, not uninstall
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
fi
%triggerun -- zoneminder < 1.25.0-4
# Save the current service runlevel info
# User must manually run systemd-sysv-convert --apply zoneminder
# to migrate them to systemd targets
/usr/bin/systemd-sysv-convert --save zoneminder >/dev/null 2>&1 ||:
# Run these because the SysV package being removed won't do them
/sbin/chkconfig --del zoneminder >/dev/null 2>&1 || :
/bin/systemctl try-restart zoneminder.service >/dev/null 2>&1 || :
%files
%defattr(-,root,root,-)
%doc AUTHORS COPYING README.md distros/fedora/README.Fedora distros/fedora/README.https distros/fedora/jscalendar-doc
%config %attr(640,root,%{zmgid_final}) /etc/zm/zm.conf
%config(noreplace) %attr(644,root,root) /etc/httpd/conf.d/zoneminder.conf
%config(noreplace) /etc/tmpfiles.d/zoneminder.conf
%config(noreplace) /etc/logrotate.d/zoneminder
%{_unitdir}/zoneminder.service
%{_bindir}/zma
%{_bindir}/zmaudit.pl
%{_bindir}/zmc
%{_bindir}/zmcontrol.pl
%{_bindir}/zmdc.pl
%{_bindir}/zmf
%{_bindir}/zmfilter.pl
%{_bindir}/zmpkg.pl
%{_bindir}/zmstreamer
%{_bindir}/zmtrack.pl
%{_bindir}/zmtrigger.pl
%{_bindir}/zmu
%{_bindir}/zmupdate.pl
%{_bindir}/zmvideo.pl
%{_bindir}/zmwatch.pl
%{_bindir}/zmcamtool.pl
%{_bindir}/zmsystemctl.pl
%{!?_without_x10:%{_bindir}/zmx10.pl}
%{perl_vendorlib}/ZoneMinder*
%{_mandir}/man*/*
%dir %{_libexecdir}/zoneminder
%{_libexecdir}/zoneminder/cgi-bin
%dir %{_datadir}/zoneminder
%{_datadir}/zoneminder/db
%{_datadir}/zoneminder/www
%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy
%{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/events
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/images
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/sock
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/swap
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/lib/zoneminder/temp
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/log/zoneminder
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /var/spool/zoneminder-upload
%dir %attr(755,%{zmuid_final},%{zmgid_final}) /run/zoneminder
%changelog
* Sat Feb 14 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
- Bump version for 1.28.1 release on Fedora 21.
* Sun Oct 5 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.0
- Bump version for 1.28.0 release.
* Fri Mar 14 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
- Tweak build requirements for cmake
* Sat Feb 01 2014 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.27
- Add zmcamtool.pl. Bump version for 1.27 release.
* Mon Dec 16 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.5
- This is a bug fixe release
- RTSP fixes, cmake enhancements, couple other misc fixes
* Mon Oct 07 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- Initial cmake build.
* Sat Oct 05 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.4
- Fedora specific path changes have been moved to zoneminder-1.26.0-defaults.patch
- All files are now part of the zoneminder source tree. Update specfile accordingly.
* Sat Sep 21 2013 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.26.3
- Initial rebuild for ZoneMinder 1.26.3 release.
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
* Mon Jan 21 2013 Adam Tkac <atkac redhat com> - 1.25.0-12
- rebuild due to "jpeg8-ABI" feature drop
* Mon Jan 7 2013 Remi Collet <rcollet@redhat.com> - 1.25.0-11
- fix configuration file for httpd 2.4, #871502
* Fri Dec 21 2012 Adam Tkac <atkac redhat com> - 1.25.0-10
- rebuild against new libjpeg
* Thu Aug 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-9
- Add patch to work around v4l2 api breakage in 3.5 kernel.
* Sun Jul 22 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.25.0-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
* Sat Jun 23 2012 Petr Pisar <ppisar@redhat.com> - 1.25.0-7
- Perl 5.16 rebuild
* Wed Mar 21 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-6
- Fix stupid thinko in sql modifications.
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-5
- Clean up macro usage.
* Sat Feb 25 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-4
- Convert to systemd.
- Add tmpfiles.d configuration since the initscript isn't around to create
/run/zoneminder.
- Remove some pointless executable permissions.
- Add logrotate file.
* Wed Feb 22 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-3
- Update README.Fedora to reference systemctl and mention timezone info in
php.ini.
- Add proper default for EYEZM_LOG_TO_FILE.
* Thu Feb 09 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-2
- Rebuild for new pcre.
* Thu Jan 19 2012 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.25.0-1
- Update to 1.25.0
- Fix gcc4.7 build problems.
- Drop gcc4.4 build fixes; for whatever reason they now break the build.
- Clean up old patches.
- Force setting of ZM_TMPDIR and ZM_RUNDIR.
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.4-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-3
- Re-add the dist-tag that somehow got lost.
* Thu Sep 15 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-2
- Add patch for bug 711780 - fix syntax issue in Mapped.pm.
- Undo that patch, and undo another which was the cause of the whole mess.
- Fix up other patches so ZM_PATH_BUILD is both defined and useful.
- Make sure database creation mods actually take.
- Update Fedora-specific docs with some additional info.
- Use bundled mootools (javascript, so no guideline violation).
- Update download location.
- Update the gcrypt patch to actually work.
- Upstream changed the tarball without changing the version to patch a
vulnerability, so redownload.
* Sun Aug 14 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.4-1
- Initial attempt to upgrade to 1.24.4.
- Add patch from BZ 460310 to build against libgcrypt instead of requiring the
gnutls openssl libs.
* Thu Jul 21 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-7.20110324svn3310
- Perl mass rebuild
* Wed Jul 20 2011 Petr Sabata <contyk@redhat.com> - 1.24.3-6.20110324svn3310
- Perl mass rebuild
* Mon May 09 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-5.20110324svn3310
- Bump for gnutls update.
* Thu Mar 24 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-4.20110324svn3310
- Update to latest 1.24.3 subversion. Turns out that what upstream was calling
1.24.3 is really just an occasionally updated devel snapshot.
- Rebase various patches.
* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 1.24.3-3
- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Tue Jan 25 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.3-1
- Update to latest upstream version.
- Rebase patches.
- Initial incomplete attempt to disable v4l1 support.
* Fri Jan 21 2011 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-6
- Unbundle cambozola; instead link to the separately pacakged copy.
- Remove BuildRoot:, %%clean and buildroot cleaning in %%install.
- Git rid of mixed space/tab usage by removing all tabs.
- Remove unnecessary Conflicts: line.
- Attempt to force short_open_tag on for the code directories.
- Move default location of sockets, swaps, logfiles and some temporary files to
make more sense and allow things to work better with a future selinux policy.
- Fix errors in README.Fedora.
* Wed Jun 02 2010 Marcela Maslanova <mmaslano@redhat.com> - 1.24.2-5
- Mass rebuild with perl-5.12.0
* Fri Dec 4 2009 Stepan Kasal <skasal@redhat.com> - 1.24.2-4
- rebuild against perl 5.10.1
- use Perl vendorarch and archlib variables correctly
* Mon Jul 27 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.24.2-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-2
- Bump release since 1.24.2-1 was mistakenly tagged a few months ago.
* Wed Jul 22 2009 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.24.2-1
- Initial update to 1.24.2.
- Rebase patches.
- Update mootools download location.
- Update to mootools 1.2.3.
- Add additional dependencies for some optional features.
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-3
- Remove unused Sys::Mmap perl dependency RPM is finding
* Sat Apr 11 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-2
- Update gcc44 patch to disable -frepo, seems to be broken with gcc44
- Added noffmpeg patch to make building outside mock easier
* Sat Mar 21 2009 Martin Ebourne <martin@zepler.org> - 1.24.1-1
- Patch for gcc 4.4 compilation errors
- Upgrade to 1.24.1
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.23.3-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Sat Jan 24 2009 Caolán McNamara <caolanm@redhat.com> - 1.23.3-3
- rebuild for dependencies
* Mon Dec 15 2008 Martin Ebourne <martin@zepler.org> - 1.23.3-2
- Fix permissions on zm.conf
* Fri Jul 11 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.23.3-1
- Initial attempt at packaging 1.23.
* Tue Jul 1 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-15
- Add perl module compat dependency, bz #453590
* Tue May 6 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-14
- Remove default runlevel, bz #441315
* Mon Apr 28 2008 Jason L Tibbitts III <tibbs@math.uh.edu> - 1.22.3-13
- Backport patch for CVE-2008-1381 from 1.23.3 to 1.22.3.
* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.22.3-12
- Autorebuild for GCC 4.3
* Thu Jan 3 2008 Martin Ebourne <martin@zepler.org> - 1.22.3-11
- Fix compilation on gcc 4.3
* Thu Dec 6 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-10
- Rebuild for new openssl
* Thu Aug 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-8
- Fix licence tag
* Thu Jul 12 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-7
- Fixes from testing by Jitz including missing dependencies and database creation
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-6
- Disable crashtrace on ppc
* Sat Jun 30 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-5
- Fix uid for directories in /var/lib/zoneminder
* Tue Jun 26 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-4
- Added perl Archive::Tar dependency
- Disabled web interface due to lack of access control on the event images
* Sun Jun 10 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-3
- Changes recommended in review by Jason Tibbitts
* Mon Apr 2 2007 Martin Ebourne <martin@zepler.org> - 1.22.3-2
- Standardised on package name of zoneminder
* Thu Dec 28 2006 Martin Ebourne <martin@zepler.org> - 1.22.3-1
- First version. Uses some parts from zm-1.20.1 by Corey DeLasaux and Serg Oskin

View File

@ -10,7 +10,7 @@
%define _without_x10 1 %define _without_x10 1
Name: zoneminder Name: zoneminder
Version: 1.29.0 Version: 1.30.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -38,7 +38,7 @@ BuildRequires: gcc gcc-c++ vlc-devel libcurl-devel libv4l-devel
BuildRequires: httpd polkit-devel BuildRequires: httpd polkit-devel
%{!?_without_ffmpeg:BuildRequires: ffmpeg} %{!?_without_ffmpeg:BuildRequires: ffmpeg}
Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc mod_ssl Requires: httpd php php-gd php-mysql cambozola polkit net-tools psmisc
Requires: libjpeg-turbo vlc-core libcurl Requires: libjpeg-turbo vlc-core libcurl
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip) Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
@ -72,6 +72,7 @@ too much degradation of performance.
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no ./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
%build %build
%cmake \ %cmake \
@ -87,6 +88,10 @@ export DESTDIR=%{buildroot}
make install make install
%post %post
# Add any new PTZ control configurations to the database (will not overwrite)
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
if [ $1 -eq 1 ] ; then if [ $1 -eq 1 ] ; then
# Initial installation # Initial installation
/bin/systemctl daemon-reload >/dev/null 2>&1 || : /bin/systemctl daemon-reload >/dev/null 2>&1 || :
@ -98,8 +103,12 @@ fi
# Upgrade from a previous version of zoneminder # Upgrade from a previous version of zoneminder
if [ $1 -eq 2 ] ; then if [ $1 -eq 2 ] ; then
# Add any new PTZ control configurations to the database (will not overwrite)
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
# Freshen the database # Freshen the database
/usr/bin/zmupdate.pl -f %{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
# We can't run this automatically when new sql account permissions need to # We can't run this automatically when new sql account permissions need to
# be manually added first # be manually added first
@ -163,9 +172,14 @@ fi
%{_bindir}/zmwatch.pl %{_bindir}/zmwatch.pl
%{_bindir}/zmcamtool.pl %{_bindir}/zmcamtool.pl
%{_bindir}/zmsystemctl.pl %{_bindir}/zmsystemctl.pl
%{_bindir}/zmtelemetry.pl
%{!?_without_x10:%{_bindir}/zmx10.pl} %{!?_without_x10:%{_bindir}/zmx10.pl}
%{_bindir}/zmonvif-probe.pl
%{perl_vendorlib}/ZoneMinder* %{perl_vendorlib}/ZoneMinder*
%{perl_vendorlib}/ONVIF*
%{perl_vendorlib}/WSDiscovery*
%{perl_vendorlib}/WSSecurity*
%{_mandir}/man*/* %{_mandir}/man*/*
%dir %{_libexecdir}/zoneminder %dir %{_libexecdir}/zoneminder
%{_libexecdir}/zoneminder/cgi-bin %{_libexecdir}/zoneminder/cgi-bin
@ -188,6 +202,9 @@ fi
%changelog %changelog
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
- Bump version fo 1.30.0 release.
* Sat Nov 21 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.29.0 * Sat Nov 21 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.29.0
- Bump version for 1.29.0 release on Fedora 23. - Bump version for 1.29.0 release on Fedora 23.

View File

@ -38,7 +38,7 @@ install(CODE "execute_process(COMMAND ln -sf ../../../../${zm_webdir}/temp \"\$E
# Opensuse cambazola? requires cambozola as a separate package so just link to it # Opensuse cambazola? requires cambozola as a separate package so just link to it
#install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")") #install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")")
# Install auxillary files required to run zoneminder on OpenSuse # Install auxiliary files required to run zoneminder on OpenSuse
install(FILES zoneminder.conf DESTINATION /etc/apache2/conf.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES zoneminder.conf DESTINATION /etc/apache2/conf.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES zoneminder.logrotate DESTINATION /etc/logrotate.d RENAME zoneminder PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zoneminder.tmpfiles DESTINATION /etc/tmpfiles.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(FILES zoneminder.tmpfiles DESTINATION /etc/tmpfiles.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

View File

@ -138,7 +138,7 @@ Upgrades
has select, insert, update, and delete permission. has select, insert, update, and delete permission.
3. You will need to upgrade the ZoneMinder database as described in the 3. You will need to upgrade the ZoneMinder database as described in the
manual. Only if the previous step was succesful, may you run zmupdate like manual. Only if the previous step was successful, may you run zmupdate like
so (as root): so (as root):
/opt/zoneminder/bin/zmupdate.pl /opt/zoneminder/bin/zmupdate.pl

View File

@ -16,7 +16,7 @@ else(ZM_TARGET_DISTRO STREQUAL "el7")
endif(ZM_TARGET_DISTRO STREQUAL "el7") endif(ZM_TARGET_DISTRO STREQUAL "el7")
# Download jscalendar & move files into position # Download jscalendar & move files into position
file(DOWNLOAD http://skylineservers.dl.sourceforge.net/project/jscalendar/jscalendar/1.0/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip LOG jsc_log STATUS download_jsc) file(DOWNLOAD http://iweb.dl.sourceforge.net/project/jscalendar/jscalendar/1.0/jscalendar-1.0.zip ${CMAKE_CURRENT_SOURCE_DIR}/jscalendar-1.0.zip LOG jsc_log STATUS download_jsc)
#message(STATUS "Log of jscalender script was: ${jsc_log}") #message(STATUS "Log of jscalender script was: ${jsc_log}")
if(download_jsc EQUAL 0) if(download_jsc EQUAL 0)
message(STATUS "Jscalander successfully downloaded. Installing...") message(STATUS "Jscalander successfully downloaded. Installing...")
@ -57,7 +57,7 @@ install(CODE "execute_process(COMMAND ln -sf ../../../../../../var/lib/zoneminde
# Link to Cambozola, which is now packaged in zmrepo # Link to Cambozola, which is now packaged in zmrepo
install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")") install(CODE "execute_process(COMMAND ln -sf ../../java/cambozola.jar \"\$ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/cambozola.jar\")")
# Install auxillary files required to run zoneminder on CentOS # Install auxiliary files required to run zoneminder on CentOS
install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(FILES redalert.wav DESTINATION ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATAROOTDIR}/zoneminder/www/sounds PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
if(ZM_TARGET_DISTRO STREQUAL "el7") if(ZM_TARGET_DISTRO STREQUAL "el7")
install(FILES zoneminder.el7.conf DESTINATION /etc/httpd/conf.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) install(FILES zoneminder.el7.conf DESTINATION /etc/httpd/conf.d RENAME zoneminder.conf PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

View File

@ -5,16 +5,14 @@ What's New
ALL permission to the ZoneMinder mysql account. This change must be done ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below. manually before ZoneMinder will run. See the installation steps below.
2. A new permission group called "Groups" has been added. This allows the 2. This package uses the HTTPS protocol by default to access the web portal.
system administrator to assign "view", "edit", or "none" permission to
normal users, without giving them access to the rest of the ZoneMinder
system. During an upgrade, existing accounts will default to a Groups
permission of "none".
3. This package now requires the HTTPS protocol to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
3. The php package that ships with CentOS 6 does not support the new ZoneMinder
API. If you require API functionality (such as using a mobile app) then you
should consider an upgrade to CentOS 7 or use Fedora.
New installs New installs
============ ============
@ -40,7 +38,7 @@ New installs
3. If you have chosen to change the zoneminder mysql credentials to something 3. If you have chosen to change the zoneminder mysql credentials to something
other than zmuser/zmpass then you must now edit /etc/zm.conf. Change other than zmuser/zmpass then you must now edit /etc/zm.conf. Change
ZM_DB_USER and ZM_DB_PASS to the values you created in step 2. ZM_DB_USER and ZM_DB_PASS to the values you created in the previous step.
Additionally, you must also edit Additionally, you must also edit
/usr/share/zoneminder/www/api/app/Config/database.php in a similar manner. /usr/share/zoneminder/www/api/app/Config/database.php in a similar manner.
@ -55,11 +53,15 @@ New installs
If you are not sure of the proper timezone specification to use, look at If you are not sure of the proper timezone specification to use, look at
http://php.net/date.timezone http://php.net/date.timezone
5. Verify the default ZoneMinder Apache configuration meets your needs: 5. Install mod_ssl or configure /etc/httpd/conf.d/zoneminder.conf to meet your
needs. This package comes preconfigured for HTTPS using the default self
signed certificate on your system. The recommended way to complete this step
is to simply install mod_ssl:
/etc/httpd/conf.d/zoneminder.conf sudo yum install mod_ssl
When in doubt, leave this configuration as it is. If this does not meet your needs, then read README.https to
learn about alternatives. When in doubt, install mod_ssl.
6. Configure the web server to start automatically: 6. Configure the web server to start automatically:
@ -122,6 +124,7 @@ New installs
/etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there /etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there
may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file
exists, inspect it and merge anything new in that file with zoneminder.conf. exists, inspect it and merge anything new in that file with zoneminder.conf.
Verify the SSL REquirements meet your needs. Read README.https if necessary.
4. Upgrade the database before starting ZoneMinder. 4. Upgrade the database before starting ZoneMinder.

View File

@ -1,17 +1,19 @@
What's New What's New
========== ==========
1. Due to the active state of the ZoneMinder project, we now recommend granting 1. The Apache ScriptAlias has been changed from "/cgi-bin/zm/zms" to
"/cgi-bin-zm/zms". This has been to done to avoid this bug:
https://bugzilla.redhat.com/show_bug.cgi?id=973067
IMPORTANT: You must manually verify the value of PATH_ZMS under Options.
Make sure it is set to "/cgi-bin-zm/nph-zms". Failure to do so will result
in a broken system. You have been warned.
2. Due to the active state of the ZoneMinder project, we now recommend granting
ALL permission to the ZoneMinder mysql account. This change must be done ALL permission to the ZoneMinder mysql account. This change must be done
manually before ZoneMinder will run. See the installation steps below. manually before ZoneMinder will run. See the installation steps below.
2. A new permission group called "Groups" has been added. This allows the 3. This package uses the HTTPS protocol by default to access the web portal.
system administrator to assign "view", "edit", or "none" permission to
normal users, without giving them access to the rest of the ZoneMinder
system. During an upgrade, existing accounts will default to a Groups
permission of "none".
3. This package now requires the HTTPS protocol to access the web portal.
Requests using HTTP will auto-redirect to HTTPS. See README.https for Requests using HTTP will auto-redirect to HTTPS. See README.https for
more information. more information.
@ -74,12 +76,22 @@ New installs
SELINUX line from "enforcing" to "disabled". This change will take SELINUX line from "enforcing" to "disabled". This change will take
effect after a reboot. effect after a reboot.
6. Now start the web server: 6. Install mod_ssl or configure /etc/httpd/conf.d/zoneminder.conf to meet your
needs. This package comes preconfigured for HTTPS using the default self
signed certificate on your system. The recommended way to complete this step
is to simply install mod_ssl:
sudo yum install mod_ssl
If this does not meet your needs, then read README.https to
learn about alternatives. When in doubt, install mod_ssl.
7. Now start the web server:
sudo systemctl enable httpd sudo systemctl enable httpd
sudo systemctl start httpd sudo systemctl start httpd
7. Now start zoneminder: 8. Now start zoneminder:
sudo systemctl enable zoneminder sudo systemctl enable zoneminder
sudo systemctl start zoneminder sudo systemctl start zoneminder
@ -118,6 +130,7 @@ Upgrades
/etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there /etc/httpd/conf.d. You will have a file called "zoneminder.conf" and there
may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file may also be a file called "zoneminder.conf.rpmnew". If the rpmnew file
exists, inspect it and merge anything new in that file with zoneminder.conf. exists, inspect it and merge anything new in that file with zoneminder.conf.
Verify the SSL REquirements meet your needs. Read README.https if necessary.
4. Upgrade the database before starting ZoneMinder. 4. Upgrade the database before starting ZoneMinder.

View File

@ -4,7 +4,7 @@
%define zmgid_final apache %define zmgid_final apache
Name: zoneminder Name: zoneminder
Version: 1.29.0 Version: 1.30.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -30,7 +30,7 @@ BuildRequires: libcurl-devel vlc-devel ffmpeg-devel polkit-devel
# cmake needs the following installed at build time due to the way it auto-detects certain parameters # cmake needs the following installed at build time due to the way it auto-detects certain parameters
BuildRequires: httpd ffmpeg BuildRequires: httpd ffmpeg
Requires: httpd php php-gd php-mysql mysql-server libjpeg-turbo cambozola polkit net-tools mod_ssl Requires: httpd php php-gd php-mysql mysql-server libjpeg-turbo cambozola polkit net-tools
Requires: psmisc perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) Requires: psmisc perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip) Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP) Requires: perl(MIME::Entity) perl(MIME::Lite) perl(Net::SMTP) perl(Net::FTP)
@ -69,6 +69,7 @@ too much degradation of performance.
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no ./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
%build %build
# Have to override CMAKE_INSTALL_LIBDIR for cmake < 2.8.7 due to this bug: # Have to override CMAKE_INSTALL_LIBDIR for cmake < 2.8.7 due to this bug:
@ -98,8 +99,12 @@ echo -e "\nCreating and installing a ZoneMinder SELinux policy module. Please wa
# Upgrade from a previous version of zoneminder # Upgrade from a previous version of zoneminder
if [ $1 -eq 2 ] ; then if [ $1 -eq 2 ] ; then
# Add any new PTZ control configurations to the database (will not overwrite)
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
# Freshen the database # Freshen the database
/usr/bin/zmupdate.pl -f %{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
# We can't run this automatically when new sql account permissions need to # We can't run this automatically when new sql account permissions need to
# be manually added first # be manually added first
@ -154,14 +159,16 @@ rm -rf %{_docdir}/%{name}-%{version}
%{_bindir}/zmwatch.pl %{_bindir}/zmwatch.pl
%{_bindir}/zmcamtool.pl %{_bindir}/zmcamtool.pl
%{_bindir}/zmsystemctl.pl %{_bindir}/zmsystemctl.pl
%{_bindir}/zmtelemetry.pl
%{_bindir}/zmx10.pl %{_bindir}/zmx10.pl
#%{_bindir}/zmonvif-probe.pl %{_bindir}/zmonvif-probe.pl
%{perl_vendorlib}/ZoneMinder* %{perl_vendorlib}/ZoneMinder*
%{perl_vendorarch}/auto/ZoneMinder/.packlist %{perl_vendorarch}/auto/ZoneMinder/.packlist
#%{perl_vendorlib}/ONVIF* %{perl_vendorarch}/auto/ONVIF/.packlist
#%{perl_vendorlib}/WSDiscovery* %{perl_vendorlib}/ONVIF*
#%{perl_vendorlib}/WSSecurity* %{perl_vendorlib}/WSDiscovery*
%{perl_vendorlib}/WSSecurity*
%{_mandir}/man*/* %{_mandir}/man*/*
%dir %{_libexecdir}/%{name} %dir %{_libexecdir}/%{name}
%{_libexecdir}/%{name}/cgi-bin %{_libexecdir}/%{name}/cgi-bin
@ -182,6 +189,9 @@ rm -rf %{_docdir}/%{name}-%{version}
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/spool/zoneminder-upload %dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/spool/zoneminder-upload
%changelog %changelog
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
- Bump version fo 1.30.0 release.
* Tue Sep 8 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1 * Tue Sep 8 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
- Require https, freshen dB on updates. - Require https, freshen dB on updates.

View File

@ -6,7 +6,7 @@
%global _hardened_build 1 %global _hardened_build 1
Name: zoneminder Name: zoneminder
Version: 1.29.0 Version: 1.30.0
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -32,7 +32,7 @@ BuildRequires: ffmpeg ffmpeg-devel perl(X10::ActiveHome) perl(Astro::SunTime)
# cmake needs the following installed at build time due to the way it auto-detects certain parameters # cmake needs the following installed at build time due to the way it auto-detects certain parameters
BuildRequires: httpd polkit-devel BuildRequires: httpd polkit-devel
Requires: httpd php php-gd php-mysql mariadb-server cambozola polkit net-tools mod_ssl Requires: httpd php php-gd php-mysql mariadb-server cambozola polkit net-tools
Requires: psmisc libjpeg-turbo vlc-core libcurl Requires: psmisc libjpeg-turbo vlc-core libcurl
Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip) Requires: perl(DBD::mysql) perl(Archive::Tar) perl(Archive::Zip)
@ -65,6 +65,7 @@ too much degradation of performance.
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes ./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no ./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no ./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
%build %build
%cmake \ %cmake \
@ -96,8 +97,12 @@ fi
# Upgrade from a previous version of zoneminder # Upgrade from a previous version of zoneminder
if [ $1 -eq 2 ] ; then if [ $1 -eq 2 ] ; then
# Add any new PTZ control configurations to the database (will not overwrite)
%{_bindir}/zmcamtool.pl --import >/dev/null 2>&1 || :
# Freshen the database # Freshen the database
/usr/bin/zmupdate.pl -f %{_bindir}/zmupdate.pl -f >/dev/null 2>&1 || :
# We can't run this automatically when new sql account permissions need to # We can't run this automatically when new sql account permissions need to
# be manually added first # be manually added first
@ -163,12 +168,16 @@ fi
%{_bindir}/zmwatch.pl %{_bindir}/zmwatch.pl
%{_bindir}/zmcamtool.pl %{_bindir}/zmcamtool.pl
%{_bindir}/zmsystemctl.pl %{_bindir}/zmsystemctl.pl
%{_bindir}/zmtelemetry.pl
%{_bindir}/zmx10.pl %{_bindir}/zmx10.pl
%{_bindir}/zmonvif-probe.pl
%{perl_vendorlib}/ZoneMinder* %{perl_vendorlib}/ZoneMinder*
%{perl_vendorarch}/auto/ZoneMinder/.packlist %{perl_vendorarch}/auto/ZoneMinder/.packlist
#%{perl_vendorlib}/%{_arch}-linux-thread-multi/auto/ZoneMinder* %{perl_vendorarch}/auto/ONVIF/.packlist
#%{perl_archlib}/ZoneMinder* %{perl_vendorlib}/ONVIF*
%{perl_vendorlib}/WSDiscovery*
%{perl_vendorlib}/WSSecurity*
%{_mandir}/man*/* %{_mandir}/man*/*
%dir %{_libexecdir}/zoneminder %dir %{_libexecdir}/zoneminder
%{_libexecdir}/zoneminder/cgi-bin %{_libexecdir}/zoneminder/cgi-bin
@ -191,6 +200,9 @@ fi
%changelog %changelog
* Thu Mar 3 2016 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.30.0
- Bump version fo 1.30.0 release.
* Mon Sep 7 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1 * Mon Sep 7 2015 Andrew Bauer <knnniggett@users.sourceforge.net> - 1.28.1
- Require https, disable selinux module, freshen dB on updates. - Require https, disable selinux module, freshen dB on updates.

View File

@ -525,7 +525,7 @@ zoneminder (1.22.3-7) unstable; urgency=low
zoneminder (1.22.3-6) unstable; urgency=low zoneminder (1.22.3-6) unstable; urgency=low
* Removed a similar bash only statment from zmpkg.pl * Removed a similar bash only statement from zmpkg.pl
(closes:414882) (closes:414882)
-- Peter Howard <pjh@northern-ridge.com.au> Sat, 14 Apr 2007 11:46:56 +1000 -- Peter Howard <pjh@northern-ridge.com.au> Sat, 14 Apr 2007 11:46:56 +1000

View File

@ -51,7 +51,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libwww-perl ,libwww-perl
,mysql-client | virtual-mysql-client ,mysql-client | virtual-mysql-client
,perl-modules ,perl-modules
,php5-mysql ,php5-mysql, php5-gd
,policykit-1 ,policykit-1
,rsyslog | system-log-daemon ,rsyslog | system-log-daemon
,zip ,zip

View File

@ -525,7 +525,7 @@ zoneminder (1.22.3-7) unstable; urgency=low
zoneminder (1.22.3-6) unstable; urgency=low zoneminder (1.22.3-6) unstable; urgency=low
* Removed a similar bash only statment from zmpkg.pl * Removed a similar bash only statement from zmpkg.pl
(closes:414882) (closes:414882)
-- Peter Howard <pjh@northern-ridge.com.au> Sat, 14 Apr 2007 11:46:56 +1000 -- Peter Howard <pjh@northern-ridge.com.au> Sat, 14 Apr 2007 11:46:56 +1000

View File

@ -238,7 +238,7 @@ The second approach is to use diagnostic images which are saved copies of the in
There are two kinds of diagnostic images which are and are written (and continuously overwritten) to the top level monitor event directory. If an event occurs then the files are additionally copied to the event directory and renamed with the appropriate frame number as a prefix. There are two kinds of diagnostic images which are and are written (and continuously overwritten) to the top level monitor event directory. If an event occurs then the files are additionally copied to the event directory and renamed with the appropriate frame number as a prefix.
The first set are produced by the monitor on the image as a whole. The diag-r.jpg image is the current reference image against which all individual frames are compared and the diag-d.jpg image is the delta image highlighting the difference between the reference image and the last analysed image. In this images identicial pixels will be black and the more different a pixel is the whiter it will be. Viewing this image and determining the colour of the pixels is a good way of getting a feel for the pixel differences you might expect (often more than you think). The first set are produced by the monitor on the image as a whole. The diag-r.jpg image is the current reference image against which all individual frames are compared and the diag-d.jpg image is the delta image highlighting the difference between the reference image and the last analysed image. In this images identical pixels will be black and the more different a pixel is the whiter it will be. Viewing this image and determining the colour of the pixels is a good way of getting a feel for the pixel differences you might expect (often more than you think).
The second set of diag images are labelled as diag-<zoneid>-<stage>.jpg where zoneid is the id of the zone in question (Smile) and the stage is where in the alarm check process the image is generated from. So if you have several zones you can expect to see multiple files. Also these files are only interested in what is happening in their zone only and will ignore anything else outside of the zone. The stages that each number represents are as follows, The second set of diag images are labelled as diag-<zoneid>-<stage>.jpg where zoneid is the id of the zone in question (Smile) and the stage is where in the alarm check process the image is generated from. So if you have several zones you can expect to see multiple files. Also these files are only interested in what is happening in their zone only and will ignore anything else outside of the zone. The stages that each number represents are as follows,
@ -617,14 +617,14 @@ How can I trouble shoot the hardware and/or software?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Here are some commands to get information about your hardware. Some commands are distribution dependent. Here are some commands to get information about your hardware. Some commands are distribution dependent.
* ``[[lspci]] -vv`` -- Returns lots of detailed info. Check for conflicting interrupts or port assignments. You can sometimes alter interrupts/ ports in bios. Try a different pci slot to get a clue if it is HW conflict (comand provided by the pciutils package). * ``[[lspci]] -vv`` -- Returns lots of detailed info. Check for conflicting interrupts or port assignments. You can sometimes alter interrupts/ ports in bios. Try a different pci slot to get a clue if it is HW conflict (command provided by the pciutils package).
* ``[[scanpci]] -v`` -- Gives you information from your hardware EPROM * ``[[scanpci]] -v`` -- Gives you information from your hardware EPROM
* ``[[lsusb]] -vv`` -- Returns lots of detail about USB devices (camand provided by usbutils package). * ``[[lsusb]] -vv`` -- Returns lots of detail about USB devices (camand provided by usbutils package).
* ``[[dmesg]]`` -- Shows you how your hardware initialized (or didn't) on boot-up. You will get the most use of this. * ``[[dmesg]]`` -- Shows you how your hardware initialized (or didn't) on boot-up. You will get the most use of this.
* ``[[v4l-info]]`` -- to see how driver is talking to card. look for unusual values. * ``[[v4l-info]]`` -- to see how driver is talking to card. look for unusual values.
* ``[[modinfo bttv]]`` -- some bttv driver stats. * ``[[modinfo bttv]]`` -- some bttv driver stats.
* ``[[zmu]] -m 0 -q -v`` -- Returns various information regarding a monitor configuration. * ``[[zmu]] -m 0 -q -v`` -- Returns various information regarding a monitor configuration.
* ``[[ipcs]] `` -- Provides information on the ipc facilities for which the calling process has read acccess. * ``[[ipcs]] `` -- Provides information on the ipc facilities for which the calling process has read access.
* ``[[ipcrm]] `` -- The ipcrm command can be used to remove an IPC object from the kernel. * ``[[ipcrm]] `` -- The ipcrm command can be used to remove an IPC object from the kernel.
* ``cat /proc/interrupts`` -- This will dispaly what interrupts your hardware is using. * ``cat /proc/interrupts`` -- This will dispaly what interrupts your hardware is using.

View File

@ -13,7 +13,7 @@ ZoneMinder Documentation
Welcome to ZoneMinder's documentation, the following resources are available Welcome to ZoneMinder's documentation, the following resources are available
:doc:`installationguide/index` :doc:`installationguide/index`
Many distrubution repos only hold older versions of ZoneMinder, current versions contain many bug fixes and updated functionality. Instructions here for installing updated packages or compiling from source. Many distribution repos only hold older versions of ZoneMinder, current versions contain many bug fixes and updated functionality. Instructions here for installing updated packages or compiling from source.
:doc:`userguide/index` :doc:`userguide/index`
Guide to setting up ZoneMinder for the first time and detailed guides for using the ZoneMinder front end. Guide to setting up ZoneMinder for the first time and detailed guides for using the ZoneMinder front end.

View File

@ -1,5 +1,5 @@
Ubuntu Ubuntu Instruction
====== ===================
.. contents:: .. contents::
@ -286,192 +286,106 @@ Harder Way: Build Package From Source
------------------------------------------- -------------------------------------------
(These instructions assume installation from source on a ubuntu 15.x+ system) (These instructions assume installation from source on a ubuntu 15.x+ system)
**Step 1:** First make sure you have the needed tools **Step 1:** Grab the package installer script
::
wget https://raw.githubusercontent.com/ZoneMinder/ZoneMinder/master/utils/do_debian_package.sh
chmod a+x do_debian_package.sh
**Step 2:** Update the system
:: ::
sudo apt-get update sudo apt-get update
sudo apt-get install cmake git
**Step 2:** Next up make sure you have all the dependencies
**Step 3** Create the package
To build the latest master snapshot:
:: ::
sudo apt-get install apache2 mysql-server php5 php5-mysql build-essential libmysqlclient-dev libssl-dev libbz2-dev libpcre3-dev libdbi-perl libarchive-zip-perl libdate-manip-perl libdevice-serialport-perl libmime-perl libpcre3 libwww-perl libdbd-mysql-perl libsys-mmap-perl yasm automake autoconf libjpeg8-dev libjpeg8 apache2 libapache2-mod-php5 php5-cli libphp-serialization-perl libgnutls-dev libjpeg8-dev libavcodec-dev libavformat-dev libswscale-dev libavutil-dev libv4l-dev libtool ffmpeg libnetpbm10-dev libavdevice-dev libmime-lite-perl dh-autoreconf dpatch policykit-1 libpolkit-gobject-1-dev libextutils-pkgconfig-perl libcurl3 libvlc-dev libcurl4-openssl-dev curl php5-gd ./do_debian_package.sh `lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'` `date +%Y%m%d`01 local master
(you are asked for the mysql root password when installing mysql server - put in a password that you'd like).
**Step 3:** Download ZoneMinder source code and compile+install: To build the latest stable release:
:: ::
git clone https://github.com/ZoneMinder/ZoneMinder.git ./do_debian_package.sh `lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'` `date +%Y%m%d`01 local stable
cd ZoneMinder/
git submodule init
git submodule update
cmake .
make
sudo make install
**Step 4:** Now make sure your symlinks to events and images are set correctly:
Note that the ``lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'`` part simply extracts your distribution name - like "vivid", "trusty" etc. You can always replace it by your distro name if you know it. As far as the script goes, it checks if your distro is "trusty" in which case it pulls in pre-systemd release configurations and if its not "trusty" it assumes its based on systemd and pulls in systemd related config files.
(At the end the script will ask if you want to retain the checked out version of zoneminder. If you are a developer and are making local changes, make sure you select "y" so that the next time you do the build process mentioned here, it keeps your changes. Selecting any other value than "y" or "Y" will delete the checked out code and only retain the package)
This should now create a bunch of .deb files
**Step 4:** Install the package
:: ::
sudo ./zmlinkcontent.sh sudo gdebi zoneminder_<version>_<arch>.deb
(example sudo gdebi zoneminder_1.29.0-vivid-2016012001_amd64.deb)
**Step 5:** Now lets make sure ZM has DB permissions to write to the DB:
**This will report DB errors - ignore - you need to configure the DB and some other stuff**
**Step 5:** Post install configuration
:: ::
sudo mysql -uroot -p < /usr/share/zoneminder/db/zm_create.sql
mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';" mysql -uroot -p -e "grant select,insert,update,delete,create,alter,index,lock tables on zm.* to 'zmuser'@localhost identified by 'zmpass';"
**Step 6:** Now lets create the DB & its tables that ZM needs sudo a2enmod cgi rewrite
::
mysql -uroot -p <db/zm_create.sql
**Step 7:** Now we need to make sure Ubuntu 15 is able to start/stop zoneminder via systemd:
::
sudo cp distros/ubuntu1504_cmake/zoneminder.service /lib/systemd/system
edit **/lib/systemd/system/zoneminder.service** file
* rename **/usr/bin/zmpkg** to **/usr/local/bin/zmpkg** everywhere
(The step above is needed because when you compile from source, it installs to /usr/local/instead of /usr/)
**Step 8:** Now lets make sure systemd recognizes this file
::
sudo systemctl daemon-reload
sudo systemctl enable zoneminder.service
**Step 9:** Now lets work on Zoneminder's apache configuration:
::
sudo cp distros/ubuntu1504_cmake/conf/apache2/zoneminder.conf /etc/apache2/conf-available/
sudo a2enconf zoneminder sudo a2enconf zoneminder
sudo a2enmod cgi
sudo a2enmod rewrite
sudo service apache2 reload
**Step 10:** Edit /etc/apache2/conf-available/zoneminder.conf and change **all** occurrences of:
* **/usr/lib/zoneminder/cgi-bin** to **/usr/local/libexec/zoneminder/cgi-bin** **Step 6:** Fix PHP TimeZone
* **/usr/share/zoneminder** to **/usr/local/share/zoneminder**
After editing your /etc/apache2/conf-available/zoneminder.conf should look like: ``sudo vi /etc/php5/apache2/php.ini``
Look for [Date] and inside it you will see a date.timezone that is commented. remove the comment and specific your timezone. Please make sure the timezone is valid (see http://php.net/manual/en/timezones.php)
Example:
``date.timezone = America/New_York``
**Step 7:** Fix some key permission issues and make sure API works
:: ::
ScriptAlias /zm/cgi-bin "/usr/local/libexec/zoneminder/cgi-bin" sudo chown www-data /etc/zm/zm.conf
<Directory "/usr/local/libexec/zoneminder/cgi-bin"> sudo chown -R www-data /usr/share/zoneminder/www/api/
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride All
Require all granted
</Directory>
Alias /zm /usr/local/share/zoneminder/www
<Directory /usr/local/share/zoneminder/www>
php_flag register_globals off
Options Indexes FollowSymLinks
<IfModule mod_dir.c>
DirectoryIndex index.php
</IfModule>
</Directory>
<Directory /usr/local/share/zoneminder/www/api> **Step 8:** Restart all services
AllowOverride All
</Directory>
**Step 11:** Now lets make sure ZM can read/write to the zoneminder directory:
:: ::
sudo chown -R www-data:www-data /usr/local/share/zoneminder/ sudo service apache2 restart
sudo service zoneminder restart
Check if ZM is running properly
**Step 12:** Make sure you can view Monitor View
1. Open up ZM, configure your monitors and verify you can view Monitor feeds
2. If not, open up ZM console in your browser, go to ``Options->Path`` and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM
**Step 13**: Edit Timezone in PHP
vi /etc/php5/apache2/php.ini
Look for [Date] and inside it you will see a date.timezone
that is commented. remove the comment and specific your timezone.
Please make sure the timezone is valid (see http://php.net/manual/en/timezones.php)
In my case:
:: ::
date.timezone = America/New_York sudo service zoneminder status
**Step 14:** Finally, lets make a config change to apache (needed for htaccess overrides to work for APIs)
Edit /etc/apache2/apache2.conf and add this: **Step 9:** Make sure streaming works - set PATH_ZMS
:: open up ZM console in your browser, go to Options->Path and make sure ``PATH_ZMS`` is set to ``/zm/cgi-bin/nph-zms`` and restart ZM
<Directory /usr/local/share>
AllowOverride All **Step 10:** Make sure everything works
Require all granted
</Directory> * point your browser to http://yourzmip/zm - you should see ZM console running
* point your browser to http://yourzmip/zm/api/host/getVersion.json - you should see an API version
Restart apache * Configure your monitors and make sure its all a-ok
::
sudo service apache2 reload
You are done. Lets proceed to make sure everything works:
Making sure ZM and APIs work:
1. open up a browser and go to ``http://localhost/zm`` - should bring up ZM
2. (OPTIONAL - just for peace of mind) open up a tab and go to ``http://localhost/zm/api`` - should bring up a screen showing CakePHP version with some green color boxes. Green is good. If you see red, or you don't see green, there may be a problem (should not happen). Ignore any warnings in yellow saying "DebugKit" not installed. You don't need it
3. open up a tab in the same browser and go to ``http://localhost/zm/api/host/getVersion.json``
If it responds with something like:
::
{
"version": "1.28.107",
"apiversion": "1.28.107.1"
}
Then your APIs are working
Make sure ZM and APIs work with security:
1. Enable OPT_AUTH in ZM
2. Log out of ZM in browser
3. Open a NEW tab in the SAME BROWSER (important) and go to ``http://localhost/zm/api/host/getVersion.json`` - should give you "Unauthorized" along with a lot more of text
4. Go to another tab in the SAME BROWSER (important) and log into ZM
5. Repeat step 3 and it should give you the ZM and API version
**Congrats** your installation is complete
Suggested changes to MySQL (Optional but recommended)
------------------------------------------------------
For most of you Zoneminder will run just fine with the default MySQL settings. There are a couple of settings that may, in time, provide beneficial especially if you have a number of cameras and many events with a lot of files. One setting we recommend is the "innodb_file_per_table" This will be a default setting in MySQL 5.6 but should be added in MySQL 5.5 which comes with Ubuntu 14.04. A description can be found here: http://dev.mysql.com/doc/refman/5.5/en/innodb-multiple-tablespaces.html
To add "innodb_file_per_table" edit the my.cnf file:
``vi /etc/mysql/my.cnf``
Under [mysqld] add
``innodb_file_per_table``
Save and exit.
Restart MySQL
``service mysql restart``

View File

@ -35,7 +35,7 @@ Type
Suppresses the detection of motion within it. This can be layered on top of any other zone type, preventing motion within the Inactive zone from being effective for any other zone type. Use inactive zones to cover areas in which nothing notable will ever happen or where you get false alarms that don't relate to what you are trying to monitor. Inactive zones may be overlaid on other zones to blank out areas, and are processed first (with the exception of Privacy zones, see below). As a general practice, you should try and make zones abut each other instead of overlapping to avoid repeated duplicate processing of the same area. Suppresses the detection of motion within it. This can be layered on top of any other zone type, preventing motion within the Inactive zone from being effective for any other zone type. Use inactive zones to cover areas in which nothing notable will ever happen or where you get false alarms that don't relate to what you are trying to monitor. Inactive zones may be overlaid on other zones to blank out areas, and are processed first (with the exception of Privacy zones, see below). As a general practice, you should try and make zones abut each other instead of overlapping to avoid repeated duplicate processing of the same area.
* Privacy * Privacy
Blackens the pixels within it. This can be used if you want to hide some regions in the image if the situation does not allow an other solution. This zone type is different to all the others in that it gets processed as soon as possible during capture (even before the timestamp gets into the image) and not in the analyzing process. So if you add, change or delete a Privacy zone, you don't see the changes in the image until the capture process gets restarted. This will be done automatically, but needs a few seconds. Blackens the pixels within it. This can be used if you want to hide some regions in the image if the situation does not allow another solution. This zone type is different to all the others in that it gets processed as soon as possible during capture (even before the timestamp gets into the image) and not in the analyzing process. So if you add, change or delete a Privacy zone, you don't see the changes in the image until the capture process gets restarted. This will be done automatically, but needs a few seconds.
Preset Preset
The preset chooser sets sensible default values based on computational needs (fast v. best) and sensitivity (low, medium, high.) It is not required that you select a preset, and you can alter any of the parameters after choosing a preset. For a small number of monitors with ZoneMinder running on modern equipment, Best, high sensitivity can be chosen as a good starting point. The preset chooser sets sensible default values based on computational needs (fast v. best) and sensitivity (low, medium, high.) It is not required that you select a preset, and you can alter any of the parameters after choosing a preset. For a small number of monitors with ZoneMinder running on modern equipment, Best, high sensitivity can be chosen as a good starting point.

View File

@ -90,7 +90,7 @@ Saving filters
.. image:: images/filter-save.png .. image:: images/filter-save.png
:width: 400px :width: 400px
When saving filters, if you want the filter to run in the background make sure you select the "Run filter in background" option. When checked, ZoneMinder will make sure the filter is checked regularly. For example, if you want to be notified of new events by email, you sould make sure this is checked. Filters that are configured to run in the background have a "*" next to it. When saving filters, if you want the filter to run in the background make sure you select the "Run filter in background" option. When checked, ZoneMinder will make sure the filter is checked regularly. For example, if you want to be notified of new events by email, you should make sure this is checked. Filters that are configured to run in the background have a "*" next to it.
For example: For example:

View File

@ -65,9 +65,9 @@ own empty screen.
* **B**: Click here to explore the various options of ZoneMinder and how to configure them. You already used this to enable authentication and change style above. Over time, you will find this to have many other things you will want to customize. * **B**: Click here to explore the various options of ZoneMinder and how to configure them. You already used this to enable authentication and change style above. Over time, you will find this to have many other things you will want to customize.
* **C**: This link, when clicked, opens up a color coded log window of what is going on in Zoneminder and often gives you good insight into what is going wrong or right. Note that the color here is red - that is an indication that some error occurred in ZoneMinder. You should click it and investigate. * **C**: This link, when clicked, opens up a color coded log window of what is going on in Zoneminder and often gives you good insight into what is going wrong or right. Note that the color here is red - that is an indication that some error occurred in ZoneMinder. You should click it and investigate.
* **D**: This is the core of ZoneMinder - recording events. It gives you a count of how many events were recorded over the hour, day, week, month. * **D**: This is the core of ZoneMinder - recording events. It gives you a count of how many events were recorded over the hour, day, week, month.
* **E**: These are the "Zones". Zones are areas within the camera that you mark as 'hotspots' for motion detection. Simply put, when you first configure your monitors (cameras), by default Zoneminder uses the entire field of view of the camera to detect motion. You may not want this. You may want to create "zones" specifically for detecting motion and ignore others. For example, lets consider a room with a fan that spins. You surely don't want to consider the fan moving continously a reason for triggering a record? Probably not - in that case, you'd leave the fan out while making your zones. * **E**: These are the "Zones". Zones are areas within the camera that you mark as 'hotspots' for motion detection. Simply put, when you first configure your monitors (cameras), by default Zoneminder uses the entire field of view of the camera to detect motion. You may not want this. You may want to create "zones" specifically for detecting motion and ignore others. For example, lets consider a room with a fan that spins. You surely don't want to consider the fan moving continuously a reason for triggering a record? Probably not - in that case, you'd leave the fan out while making your zones.
* **F**: This is the "source" column that tells you the type of the camera - if its an IP camera, a USB camera or more. In this example, they are all IP cameras. Note the color red on item F ? Well that means there is something wrong with that camera. No wonder the log also shows red. Good indication for you to tap on logs and investigate * **F**: This is the "source" column that tells you the type of the camera - if its an IP camera, a USB camera or more. In this example, they are all IP cameras. Note the color red on item F ? Well that means there is something wrong with that camera. No wonder the log also shows red. Good indication for you to tap on logs and investigate
* **G**: This defines how Zoneminder will record events. There are various modes. In brief Modect == record if a motion is detected,Record = always record 24x7, Mocord = always record PLUS detect motion, Monitor = just provide a live view but don't record anytime, Modect = Don't record till an externa entity via zmtrigger tells Zoneminder to (this is advanced usage). * **G**: This defines how Zoneminder will record events. There are various modes. In brief Modect == record if a motion is detected,Record = always record 24x7, Mocord = always record PLUS detect motion, Monitor = just provide a live view but don't record anytime, Nodect = Don't record till an externa entity via zmtrigger tells Zoneminder to (this is advanced usage).
* **H**: If you click on these links you can view a "Montage" of all your configured monitors or cycle through each one * **H**: If you click on these links you can view a "Montage" of all your configured monitors or cycle through each one

View File

@ -25,9 +25,9 @@ FORCED_ALARM_SCORE - The 'zmu' utility can be used to force an alarm on a monito
BULK_FRAME_INTERVAL - Traditionally ZoneMinder writes an entry into the Frames database table for each frame that is captured and saved. This works well in motion detection scenarios but when in a DVR situation ('Record' or 'Mocord' mode) this results in a huge number of frame writes and a lot of database and disk bandwidth for very little additional information. Setting this to a non-zero value will enabled ZoneMinder to group these non-alarm frames into one 'bulk' frame entry which saves a lot of bandwidth and space. The only disadvantage of this is that timing information for individual frames is lost but in constant frame rate situations this is usually not significant. This setting is ignored in Modect mode and individual frames are still written if an alarm occurs in Mocord mode also. BULK_FRAME_INTERVAL - Traditionally ZoneMinder writes an entry into the Frames database table for each frame that is captured and saved. This works well in motion detection scenarios but when in a DVR situation ('Record' or 'Mocord' mode) this results in a huge number of frame writes and a lot of database and disk bandwidth for very little additional information. Setting this to a non-zero value will enabled ZoneMinder to group these non-alarm frames into one 'bulk' frame entry which saves a lot of bandwidth and space. The only disadvantage of this is that timing information for individual frames is lost but in constant frame rate situations this is usually not significant. This setting is ignored in Modect mode and individual frames are still written if an alarm occurs in Mocord mode also.
EVENT_CLOSE_MODE - When a monitor is running in a continuous recording mode (Record or Mocord) events are usually closed after a fixed period of time (the section length). However in Mocord mode it is possible that motion detection may occur near the end of a section. This option controls what happens when an alarm occurs in Mocord mode. The 'time' setting means that the event will be closed at the end of the section regardless of alarm activity. The 'idle' setting means that the event will be closed at the end of the section if there is no alarm activity occuring at the time otherwise it will be closed once the alarm is over meaning the event may end up being longer than the normal section length. The 'alarm' setting means that if an alarm occurs during the event, the event will be closed once the alarm is over regardless of when this occurs. This has the effect of limiting the number of alarms to one per event and the events will be shorter than the section length if an alarm has occurred. EVENT_CLOSE_MODE - When a monitor is running in a continuous recording mode (Record or Mocord) events are usually closed after a fixed period of time (the section length). However in Mocord mode it is possible that motion detection may occur near the end of a section. This option controls what happens when an alarm occurs in Mocord mode. The 'time' setting means that the event will be closed at the end of the section regardless of alarm activity. The 'idle' setting means that the event will be closed at the end of the section if there is no alarm activity occurring at the time otherwise it will be closed once the alarm is over meaning the event may end up being longer than the normal section length. The 'alarm' setting means that if an alarm occurs during the event, the event will be closed once the alarm is over regardless of when this occurs. This has the effect of limiting the number of alarms to one per event and the events will be shorter than the section length if an alarm has occurred.
CREATE_ANALYSIS_IMAGES - By default during an alarm ZoneMinder records both the raw captured image and one that has been analysed and had areas where motion was detected outlined. This can be very useful during zone configuration or in analysing why events occured. However it also incurs some overhead and in a stable system may no longer be necessary. This parameter allows you to switch the generation of these images off. CREATE_ANALYSIS_IMAGES - By default during an alarm ZoneMinder records both the raw captured image and one that has been analysed and had areas where motion was detected outlined. This can be very useful during zone configuration or in analysing why events occurred. However it also incurs some overhead and in a stable system may no longer be necessary. This parameter allows you to switch the generation of these images off.
WEIGHTED_ALARM_CENTRES - ZoneMinder will always calculate the centre point of an alarm in a zone to give some indication of where on the screen it is. This can be used by the experimental motion tracking feature or your own custom extensions. In the alarmed or filtered pixels mode this is a simple midpoint between the extents of the detected pxiesl. However in the blob method this can instead be calculated using weighted pixel locations to give more accurate positioning for irregularly shaped blobs. This method, while more precise is also slower and so is turned off by default. WEIGHTED_ALARM_CENTRES - ZoneMinder will always calculate the centre point of an alarm in a zone to give some indication of where on the screen it is. This can be used by the experimental motion tracking feature or your own custom extensions. In the alarmed or filtered pixels mode this is a simple midpoint between the extents of the detected pxiesl. However in the blob method this can instead be calculated using weighted pixel locations to give more accurate positioning for irregularly shaped blobs. This method, while more precise is also slower and so is turned off by default.

View File

@ -1,5 +1,5 @@
Options - Servers Options - Servers
--------------- -----------------
.. image:: images/Options_Servers.png .. image:: images/Options_Servers.png

View File

@ -25,9 +25,9 @@ FILTER_EXECUTE_INTERVAL - ZoneMinder allows you to save filters to the database
MAX_RESTART_DELAY - The zmdc (zm daemon control) process controls when processeses are started or stopped and will attempt to restart any that fail. If a daemon fails frequently then a delay is introduced between each restart attempt. If the daemon stills fails then this delay is increased to prevent extra load being placed on the system by continual restarts. This option controls what this maximum delay is. MAX_RESTART_DELAY - The zmdc (zm daemon control) process controls when processeses are started or stopped and will attempt to restart any that fail. If a daemon fails frequently then a delay is introduced between each restart attempt. If the daemon stills fails then this delay is increased to prevent extra load being placed on the system by continual restarts. This option controls what this maximum delay is.
WATCH_CHECK_INTERVAL - The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinately). This option determines how often the daemons are checked. WATCH_CHECK_INTERVAL - The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinitely). This option determines how often the daemons are checked.
WATCH_MAX_DELAY - The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinately). This option determines the maximum delay to allow since the last captured frame. The daemon will be restarted if it has not captured any images after this period though the actual restart may take slightly longer in conjunction with the check interval value above. WATCH_MAX_DELAY - The zmwatch daemon checks the image capture performance of the capture daemons to ensure that they have not locked up (rarely a sync error may occur which blocks indefinitely). This option determines the maximum delay to allow since the last captured frame. The daemon will be restarted if it has not captured any images after this period though the actual restart may take slightly longer in conjunction with the check interval value above.
RUN_AUDIT - The zmaudit daemon exists to check that the saved information in the database and on the filesystem match and are consistent with each other. If an error occurs or if you are using 'fast deletes' it may be that database records are deleted but files remain. In this case, and similar, zmaudit will remove redundant information to synchronise the two data stores. This option controls whether zmaudit is run in the background and performs these checks and fixes continuously. This is recommended for most systems however if you have a very large number of events the process of scanning the database and filesystem may take a long time and impact performance. In this case you may prefer to not have zmaudit running unconditionally and schedule occasional checks at other, more convenient, times. RUN_AUDIT - The zmaudit daemon exists to check that the saved information in the database and on the filesystem match and are consistent with each other. If an error occurs or if you are using 'fast deletes' it may be that database records are deleted but files remain. In this case, and similar, zmaudit will remove redundant information to synchronise the two data stores. This option controls whether zmaudit is run in the background and performs these checks and fixes continuously. This is recommended for most systems however if you have a very large number of events the process of scanning the database and filesystem may take a long time and impact performance. In this case you may prefer to not have zmaudit running unconditionally and schedule occasional checks at other, more convenient, times.

View File

@ -19,7 +19,7 @@ UPLOAD_PORT - You can use filters to instruct ZoneMinder to upload events to a r
UPLOAD_USER - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the username that ZoneMinder should use to log in for transfer. UPLOAD_USER - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the username that ZoneMinder should use to log in for transfer.
UPLOAD_PASS - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the password that ZoneMinder should use to log in for transfer. If you are using certicate based logins for SFTP servers you can leave this option blank. UPLOAD_PASS - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the password that ZoneMinder should use to log in for transfer. If you are using certificate based logins for SFTP servers you can leave this option blank.
UPLOAD_LOC_DIR - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the local directory that ZoneMinder should use for temporary upload files. These are files that are created from events, uploaded and then deleted. UPLOAD_LOC_DIR - You can use filters to instruct ZoneMinder to upload events to a remote server. This option indicates the local directory that ZoneMinder should use for temporary upload files. These are files that are created from events, uploaded and then deleted.

View File

@ -5,7 +5,7 @@ Options - X10
OPT_X10 - If you have an X10 Home Automation setup in your home you can use ZoneMinder to initiate or react to X10 signals if your computer has the appropriate interface controller. This option indicates whether X10 options will be available in the browser client. OPT_X10 - If you have an X10 Home Automation setup in your home you can use ZoneMinder to initiate or react to X10 signals if your computer has the appropriate interface controller. This option indicates whether X10 options will be available in the browser client.
X10_DEVICE - If you have an X10 controller device (e.g. XM10U) connected to your computer this option details which port it is conected on, the default of /dev/ttyS0 maps to serial or com port 1. X10_DEVICE - If you have an X10 controller device (e.g. XM10U) connected to your computer this option details which port it is connected on, the default of /dev/ttyS0 maps to serial or com port 1.
X10_HOUSE_CODE - X10 devices are grouped together by identifying them as all belonging to one House Code. This option details what that is. It should be a single letter between A and P. X10_HOUSE_CODE - X10 devices are grouped together by identifying them as all belonging to one House Code. This option details what that is. It should be a single letter between A and P.

View File

@ -20,7 +20,7 @@ Here is an example of viewing an event stream:
* **A**: Administrative Event options on the event including viewing individual frames * **A**: Administrative Event options on the event including viewing individual frames
* **B**: The actual image stream * **B**: The actual image stream
* **C**: Navigation control * **C**: Navigation control
* **D**: You can switch between watching a single event or Continous mode (where it advances to the next event after playback is complete) * **D**: You can switch between watching a single event or Continuous mode (where it advances to the next event after playback is complete)
* **E**: Event progress bar - how much of the current event has been played back * **E**: Event progress bar - how much of the current event has been played back
You will notice for the first time that alarm images now contain an overlay outlining the blobs that represent the alarmed area. This outline is in the colour defined for that zone and lets you see what it was that caused the alarm. Clicking on one of the thumbnails will take you to a full size window where you can see the image in all its detail and scroll through the various images that make up the event. If you have the ZM_RECORD_EVENT_STATS option on, you will be able to click the 'Stats' link here and get some analysis of the cause of the event. You will notice for the first time that alarm images now contain an overlay outlining the blobs that represent the alarmed area. This outline is in the colour defined for that zone and lets you see what it was that caused the alarm. Clicking on one of the thumbnails will take you to a full size window where you can see the image in all its detail and scroll through the various images that make up the event. If you have the ZM_RECORD_EVENT_STATS option on, you will be able to click the 'Stats' link here and get some analysis of the cause of the event.

102
onvif/README Normal file
View File

@ -0,0 +1,102 @@
ZoneMinder ONVIF support
Copyright (C) 2016 Jan M. Hochstein
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--------------------------------------------------------------------------
1. PURPOSE
----------
The files in this folder and its subfolders add ONVIF support to zoneminder.
The ONVIF consortium (www.onvif.org) publishes the ONVIF specifications. These
specifications describe ways of connecting to and communicating with network
video devices. Hardware and software that adhere to these specifications are
meant to be interoperable.
2. SUBFOLDERS
-------------
doc/ - Documentation
modules/ - perl modules necessary for SOAP communication
proxy/ - perl SOAP proxy modules generated according to the ONVIF
specifications
scripts/ - application logic
wsdl/ - (empty) this is only used during the proxy generation process
3. LICENSE
----------
Any files in this folder and its subfolders are published under the same
license as this file if they do not carry additional license information.
4. PROXY GENERATION
-------------------
SOAP messages use XML format and need to comply to the schema expected by the
receiver. While it is possible to build messages through string concatenation
it is impractical for all but testing purposes.
Here we use SOAP proxy modules generated by the script wsdl2perl.pl from the
SOAP::WSDL module (http://search.cpan.org/~mkutter/SOAP-WSDL-2.00.10/)
version 2.00.10.
A - Get the input files.
Download these files and any web service (.wsdl) or schema (.xsd)
files referenced therein into the wsdl/ subfolder.
http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl
http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl
The complete list of files we have during build is:
analytics.wsdl
b-2.xsd
bf-2.xsd
br-2.xsd
brw-2.wsdl
bw-2.wsdl
devicemgmt.wsdl
media.wsdl
onvif.xsd
ptz.wsdl
r-2.xsd
rw-2.wsdl
soap-envelop.xsd
t-1.xsd
wsdd-discovery-1.1-schema-os.xsd
wsdd-discovery-1.1-wsdl-os.wsdl
wsdiscovery-udp.wsdl
wsdl11soap12.xsd
wsdl.xsd
wsnotification.wsdl
xmlmime.xsd
xop-include.xsd
B - Generate the proxy modules using these commands.
wsdl2perl.pl -p ONVIF::Device:: -b proxy/lib file:wsdl/devicemgmt.wsdl
wsdl2perl.pl -p ONVIF::Media:: -b proxy/lib file:wsdl/media.wsdl
wsdl2perl.pl -p ONVIF::PTZ:: -b proxy/lib file:wsdl/ptz.wsdl
wsdl2perl.pl -p ONVIF::Event:: -b proxy/lib file:wsdl/event.wsdl
wsdl2perl.pl -p ONVIF::Analytics:: -b proxy/lib file:wsdl/analytics.wsdl
wsdl2perl.pl -p WSDiscovery:: -b proxy/lib file:wsdl/wsdiscovery-udp.wsdl
wsdl2perl.pl -p WSNotification:: -b proxy/lib file:wsdl/wsnotification.wsdl
I had to tweak SOAP::WSDL a little bit to get correct proxies.

View File

@ -1,7 +1,7 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder ONVIF Client module # ZoneMinder ONVIF Client module
# Copyright (C) Jan M. Hochstein # Copyright (C) 2014 Jan M. Hochstein
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License

View File

@ -1,4 +1,27 @@
#!/usr/bin/perl # ==========================================================================
#
# ZoneMinder ONVIF Client module
# Copyright (C) 2014 Jan M. Hochstein
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of a SOAP message parser
#
package ONVIF::Deserializer::MessageParser; package ONVIF::Deserializer::MessageParser;
use strict; use warnings; use strict; use warnings;

View File

@ -1,3 +1,27 @@
# ==========================================================================
#
# ZoneMinder ONVIF Client module
# Copyright (C) 2014 Jan M. Hochstein
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of a SOAP deserializer
#
package ONVIF::Deserializer::XSD; package ONVIF::Deserializer::XSD;
use strict; use strict;
use warnings; use warnings;

View File

@ -1,4 +1,27 @@
#!/usr/bin/perl -w # ==========================================================================
#
# ZoneMinder ONVIF Client module
# Copyright (C) 2014 Jan M. Hochstein
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the base class for the SOAP serializers
#
package ONVIF::Serializer::Base; package ONVIF::Serializer::Base;
use strict; use strict;
use warnings; use warnings;

View File

@ -1,4 +1,27 @@
#!/usr/bin/perl -w # ==========================================================================
#
# ZoneMinder ONVIF Client module
# Copyright (C) 2014 Jan M. Hochstein
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the SOAP 1.1 serializer
#
package ONVIF::Serializer::SOAP11; package ONVIF::Serializer::SOAP11;
use strict; use strict;
use warnings; use warnings;

View File

@ -1,4 +1,27 @@
#!/usr/bin/perl -w # ==========================================================================
#
# ZoneMinder ONVIF Client module
# Copyright (C) 2014 Jan M. Hochstein
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the SOAP 1.2 serializer
#
package ONVIF::Serializer::SOAP12; package ONVIF::Serializer::SOAP12;
use strict; use strict;
use warnings; use warnings;

View File

@ -1,7 +1,7 @@
# ========================================================================== # ==========================================================================
# #
# Perl WS-Discovery implementation # Perl WS-Discovery implementation
# Copyright (C) Jan M. Hochstein # Copyright (C) 2014 Jan M. Hochstein
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License

View File

@ -1,7 +1,7 @@
# ========================================================================== # ==========================================================================
# #
# Perl WS-Security header for SOAP::WSDL # Perl WS-Security header for SOAP::WSDL
# Copyright (C) Jan M. Hochstein # Copyright (C) 2014 Jan M. Hochstein
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License
@ -26,7 +26,7 @@ use strict;
use warnings; use warnings;
use SOAP::WSDL::Factory::Serializer; use SOAP::WSDL::Factory::Serializer;
use Time::Local; use Time::Local;
use Digest::SHA1; use Digest::SHA;
use MIME::Base64; use MIME::Base64;
@ -94,7 +94,7 @@ sub ws_authen {
my $nonce = $nonce_generator->(); my $nonce = $nonce_generator->();
my $timestamp = timestamp(); my $timestamp = timestamp();
my $pwDigest = Digest::SHA1::sha1( $nonce . $timestamp . $password ); my $pwDigest = Digest::SHA::sha1( $nonce . $timestamp . $password );
my $passwordHash = MIME::Base64::encode_base64($pwDigest,""); my $passwordHash = MIME::Base64::encode_base64($pwDigest,"");
my $nonceHash = MIME::Base64::encode_base64($nonce,""); my $nonceHash = MIME::Base64::encode_base64($nonce,"");

View File

@ -1,4 +1,9 @@
# CMakeLists.txt for the ZoneMinder perl scripts. # CMakeLists.txt for the ZoneMinder perl scripts.
# If this is an out-of-source build, copy the files we need to the binary directory
if(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
endif(NOT (CMAKE_BINARY_DIR STREQUAL CMAKE_SOURCE_DIR))
# Install the perl scripts # Install the perl scripts
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmonvif-probe.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)

View File

@ -3,7 +3,7 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder ONVIF Control Protocol Module # ZoneMinder ONVIF Control Protocol Module
# Copyright (C) Jan M. Hochstein # Copyright (C) 2014 Jan M. Hochstein
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License # modify it under the terms of the GNU General Public License

View File

@ -1,586 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
Copyright (C) OASIS Open (2004-2006). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-->
<xsd:schema
targetNamespace="http://docs.oasis-open.org/wsn/b-2"
xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:wsrf-bf="http://docs.oasis-open.org/wsrf/bf-2"
xmlns:wstop="http://docs.oasis-open.org/wsn/t-1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- ======================== Imports ============================ -->
<xsd:import namespace="http://www.w3.org/2005/08/addressing"
schemaLocation="http://www.w3.org/2005/08/addressing/ws-addr.xsd"
/>
<xsd:import namespace="http://docs.oasis-open.org/wsrf/bf-2"
schemaLocation="file:wsdl/bf-2.xsd"/>
<!-- schemaLocation="http://docs.oasis-open.org/wsrf/bf-2.xsd" /> -->
<xsd:import namespace="http://docs.oasis-open.org/wsn/t-1"
schemaLocation="file:wsdl/t-1.xsd"
/>
<!-- ===================== Misc. Helper Types ===================== -->
<xsd:complexType name="QueryExpressionType" mixed="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
</xsd:sequence>
<xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
</xsd:complexType>
<xsd:complexType name="TopicExpressionType" mixed="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
</xsd:sequence>
<xsd:attribute name="Dialect" type="xsd:anyURI" use="required" />
<xsd:anyAttribute/>
</xsd:complexType>
<xsd:complexType name="FilterType">
<xsd:sequence>
<!-- extension for zonemider ONVIF -->
<xsd:element ref="wsnt:TopicExpression"
minOccurs="0" maxOccurs="unbounded" />
<xsd:element ref="wsnt:MessageContent"
minOccurs="0" maxOccurs="unbounded" />
<!-- end extension -->
<xsd:any minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="SubscriptionPolicyType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
<!-- =============== Resource Property Related =================== -->
<!-- ======== Resource Properties for NotificationProducer ======== -->
<xsd:element name="TopicExpression" type="wsnt:TopicExpressionType"/>
<xsd:element name="FixedTopicSet" type="xsd:boolean" default="true"/>
<xsd:element name="TopicExpressionDialect" type="xsd:anyURI"/>
<xsd:element name="NotificationProducerRP">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="wsnt:TopicExpression"
minOccurs="0" maxOccurs="unbounded" />
<xsd:element ref="wsnt:FixedTopicSet"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:TopicExpressionDialect"
minOccurs="0" maxOccurs="unbounded" />
<xsd:element ref="wstop:TopicSet"
minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- ======== Resource Properties for SubscriptionManager ========= -->
<xsd:element name="ConsumerReference"
type="wsa:EndpointReferenceType" />
<xsd:element name="Filter" type="wsnt:FilterType" />
<xsd:element name="SubscriptionPolicy" type="wsnt:SubscriptionPolicyType" />
<xsd:element name="CreationTime" type="xsd:dateTime" />
<xsd:element name="SubscriptionManagerRP" >
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="wsnt:ConsumerReference"
minOccurs="1" maxOccurs="1" />
<xsd:element ref="wsnt:Filter"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:SubscriptionPolicy"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:CreationTime"
minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- ================= Notification Metadata ===================== -->
<xsd:element name="SubscriptionReference"
type="wsa:EndpointReferenceType" />
<xsd:element name="Topic"
type="wsnt:TopicExpressionType" />
<xsd:element name="ProducerReference"
type="wsa:EndpointReferenceType" />
<!-- ================== Message Helper Types ===================== -->
<xsd:complexType name="NotificationMessageHolderType" >
<xsd:sequence>
<xsd:element ref="wsnt:SubscriptionReference"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:Topic"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:ProducerReference"
minOccurs="0" maxOccurs="1" />
<xsd:element name="Message">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##any" processContents="lax"
minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="NotificationMessage"
type="wsnt:NotificationMessageHolderType"/>
<!-- ========== Message Types for NotificationConsumer =========== -->
<xsd:element name="Notify" >
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="wsnt:NotificationMessage"
minOccurs="1" maxOccurs="unbounded" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<!-- ========== Message Types for NotificationProducer =========== -->
<xsd:simpleType name="AbsoluteOrRelativeTimeType">
<xsd:union memberTypes="xsd:dateTime xsd:duration" />
</xsd:simpleType>
<xsd:element name="CurrentTime" type="xsd:dateTime" />
<xsd:element name="TerminationTime"
nillable="true" type="xsd:dateTime" />
<xsd:element name="ProducerProperties"
type="wsnt:QueryExpressionType" />
<xsd:element name="MessageContent"
type="wsnt:QueryExpressionType" />
<xsd:element name="UseRaw"><xsd:complexType/></xsd:element>
<xsd:element name="Subscribe" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ConsumerReference"
type="wsa:EndpointReferenceType"
minOccurs="1" maxOccurs="1" />
<xsd:element name="Filter"
type="wsnt:FilterType"
minOccurs="0" maxOccurs="1" />
<xsd:element name="InitialTerminationTime"
type="wsnt:AbsoluteOrRelativeTimeType"
nillable="true"
minOccurs="0" maxOccurs="1" />
<xsd:element name="SubscriptionPolicy"
minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##any" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="SubscribeResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="SubscriptionReference"
type="wsa:EndpointReferenceType"
minOccurs="1" maxOccurs="1" />
<xsd:element ref="wsnt:CurrentTime"
minOccurs="0" maxOccurs="1" />
<xsd:element ref="wsnt:TerminationTime"
minOccurs="0" maxOccurs="1" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetCurrentMessage">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Topic"
type="wsnt:TopicExpressionType" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetCurrentMessageResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="SubscribeCreationFailedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="SubscribeCreationFailedFault"
type="wsnt:SubscribeCreationFailedFaultType"/>
<xsd:complexType name="InvalidFilterFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType">
<xsd:sequence>
<xsd:element name="UnknownFilter" type="xsd:QName"
minOccurs="1" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="InvalidFilterFault"
type="wsnt:InvalidFilterFaultType"/>
<xsd:complexType name="TopicExpressionDialectUnknownFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="TopicExpressionDialectUnknownFault"
type="wsnt:TopicExpressionDialectUnknownFaultType"/>
<xsd:complexType name="InvalidTopicExpressionFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="InvalidTopicExpressionFault"
type="wsnt:InvalidTopicExpressionFaultType"/>
<xsd:complexType name="TopicNotSupportedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="TopicNotSupportedFault"
type="wsnt:TopicNotSupportedFaultType"/>
<xsd:complexType name="MultipleTopicsSpecifiedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="MultipleTopicsSpecifiedFault"
type="wsnt:MultipleTopicsSpecifiedFaultType"/>
<xsd:complexType name="InvalidProducerPropertiesExpressionFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="InvalidProducerPropertiesExpressionFault"
type="wsnt:InvalidProducerPropertiesExpressionFaultType"/>
<xsd:complexType name="InvalidMessageContentExpressionFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="InvalidMessageContentExpressionFault"
type="wsnt:InvalidMessageContentExpressionFaultType"/>
<xsd:complexType name="UnrecognizedPolicyRequestFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType">
<xsd:sequence>
<xsd:element name="UnrecognizedPolicy" type="xsd:QName"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnrecognizedPolicyRequestFault"
type="wsnt:UnrecognizedPolicyRequestFaultType"/>
<xsd:complexType name="UnsupportedPolicyRequestFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType">
<xsd:sequence>
<xsd:element name="UnsupportedPolicy" type="xsd:QName"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnsupportedPolicyRequestFault"
type="wsnt:UnsupportedPolicyRequestFaultType"/>
<xsd:complexType name="NotifyMessageNotSupportedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="NotifyMessageNotSupportedFault"
type="wsnt:NotifyMessageNotSupportedFaultType"/>
<xsd:complexType name="UnacceptableInitialTerminationTimeFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType">
<xsd:sequence>
<xsd:element name="MinimumTime" type="xsd:dateTime"/>
<xsd:element name="MaximumTime" type="xsd:dateTime"
minOccurs="0"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnacceptableInitialTerminationTimeFault"
type="wsnt:UnacceptableInitialTerminationTimeFaultType"/>
<xsd:complexType name="NoCurrentMessageOnTopicFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="NoCurrentMessageOnTopicFault"
type="wsnt:NoCurrentMessageOnTopicFaultType"/>
<!-- ======== Message Types for PullPoint ======================== -->
<xsd:element name="GetMessages">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MaximumNumber"
type="xsd:nonNegativeInteger"
minOccurs="0"/>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:element name="GetMessagesResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="wsnt:NotificationMessage"
minOccurs="0" maxOccurs="unbounded" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:element name="DestroyPullPoint">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:element name="DestroyPullPointResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="UnableToGetMessagesFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnableToGetMessagesFault"
type="wsnt:UnableToGetMessagesFaultType"/>
<xsd:complexType name="UnableToDestroyPullPointFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnableToDestroyPullPointFault"
type="wsnt:UnableToDestroyPullPointFaultType"/>
<!-- ======== Message Types for Create PullPoint ================= -->
<xsd:element name="CreatePullPoint">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:element name="CreatePullPointResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="PullPoint"
type="wsa:EndpointReferenceType"/>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:anyAttribute/>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="UnableToCreatePullPointFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnableToCreatePullPointFault"
type="wsnt:UnableToCreatePullPointFaultType"/>
<!-- ======== Message Types for Base SubscriptionManager ========= -->
<xsd:element name="Renew">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="TerminationTime"
type="wsnt:AbsoluteOrRelativeTimeType"
nillable="true"
minOccurs="1" maxOccurs="1" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="RenewResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="wsnt:TerminationTime"
minOccurs="1" maxOccurs="1" />
<xsd:element ref="wsnt:CurrentTime"
minOccurs="0" maxOccurs="1" />
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="UnacceptableTerminationTimeFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType">
<xsd:sequence>
<xsd:element name="MinimumTime" type="xsd:dateTime"/>
<xsd:element name="MaximumTime" type="xsd:dateTime"
minOccurs="0"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnacceptableTerminationTimeFault"
type="wsnt:UnacceptableTerminationTimeFaultType"/>
<xsd:element name="Unsubscribe">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="UnsubscribeResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="UnableToDestroySubscriptionFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="UnableToDestroySubscriptionFault"
type="wsnt:UnableToDestroySubscriptionFaultType"/>
<!-- ====== Message Types for Pausable SubscriptionManager ======= -->
<xsd:element name="PauseSubscription">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="PauseSubscriptionResponse" >
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ResumeSubscription">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ResumeSubscriptionResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="PauseFailedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="PauseFailedFault"
type="wsnt:PauseFailedFaultType"/>
<xsd:complexType name="ResumeFailedFaultType">
<xsd:complexContent>
<xsd:extension base="wsrf-bf:BaseFaultType"/>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="ResumeFailedFault"
type="wsnt:ResumeFailedFaultType"/>
</xsd:schema>

View File

@ -1,86 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification, can be obtained from the OASIS Executive Director.
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
Copyright (C) OASIS Open (2005). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-->
<xsd:schema
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:wsrf-bf=
"http://docs.oasis-open.org/wsrf/bf-2"
elementFormDefault="qualified" attributeFormDefault="unqualified"
targetNamespace=
"http://docs.oasis-open.org/wsrf/bf-2">
<xsd:import
namespace="http://www.w3.org/2005/08/addressing"
schemaLocation=
"http://www.w3.org/2005/08/addressing/ws-addr.xsd"/>
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd">
<xsd:annotation>
<xsd:documentation>
Get access to the xml: attribute groups for xml:lang as declared on 'schema'
and 'documentation' below
</xsd:documentation>
</xsd:annotation>
</xsd:import>
<!-- ====================== BaseFault Types ======================= -->
<xsd:element name="BaseFault" type="wsrf-bf:BaseFaultType"/>
<xsd:complexType name="BaseFaultType">
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="Timestamp" type="xsd:dateTime"
minOccurs="1" maxOccurs="1"/>
<xsd:element name="Originator" type="wsa:EndpointReferenceType"
minOccurs="0" maxOccurs="1"/>
<xsd:element name="ErrorCode"
minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:complexContent mixed="true">
<xsd:extension base="xsd:anyType">
<xsd:attribute name="dialect" type="xsd:anyURI"
use="required"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="Description"
minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute ref="xml:lang" use="optional"/>
<!-- <xsd:anyAttribute processContents="lax" />-->
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="FaultCause" minOccurs="0" maxOccurs="1">
<xsd:complexType>
<xsd:sequence>
<xsd:any namespace="##other" processContents="lax"
minOccurs="1" maxOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:anyAttribute namespace="##other" processContents="lax"/>
</xsd:complexType>
</xsd:schema>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!-- Schema for the SOAP/1.1 envelope
Portions © 2001 DevelopMentor.
© 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.
This document is governed by the W3C Software License [1] as described in the FAQ [2].
[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
By obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:
Permission to use, copy, modify, and distribute this software and its documentation, with or without modification, for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:
1. The full text of this NOTICE in a location viewable to users of the redistributed or derivative work.
2. Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: "Copyright © 2001 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/"
3. Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)
Original W3C files; http://www.w3.org/2001/06/soap-envelope
Changes made:
- reverted namespace to http://schemas.xmlsoap.org/soap/envelope/
- reverted mustUnderstand to only allow 0 and 1 as lexical values
- made encodingStyle a global attribute 20020825
- removed default value from mustUnderstand attribute declaration
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.
The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"
targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" >
<!-- Envelope, header and body -->
<xs:element name="Envelope" type="tns:Envelope" />
<xs:complexType name="Envelope" >
<xs:sequence>
<xs:element ref="tns:Header" minOccurs="0" />
<xs:element ref="tns:Body" minOccurs="1" />
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Header" type="tns:Header" />
<xs:complexType name="Header" >
<xs:sequence>
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
<!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. -->
<xs:attribute name="mustUnderstand" >
<xs:simpleType>
<xs:restriction base='xs:boolean'>
<xs:pattern value='0|1' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="actor" type="xs:anyURI" />
<xs:simpleType name="encodingStyle" >
<xs:annotation>
<xs:documentation>
'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
</xs:documentation>
</xs:annotation>
<xs:list itemType="xs:anyURI" />
</xs:simpleType>
<xs:attribute name="encodingStyle" type="tns:encodingStyle" />
<xs:attributeGroup name="encodingStyle" >
<xs:attribute ref="tns:encodingStyle" />
</xs:attributeGroup>
<xs:element name="Fault" type="tns:Fault" />
<xs:complexType name="Fault" final="extension" >
<xs:annotation>
<xs:documentation>
Fault reporting structure
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="faultcode" type="xs:QName" />
<xs:element name="faultstring" type="xs:string" />
<xs:element name="faultactor" type="xs:anyURI" minOccurs="0" />
<xs:element name="detail" type="tns:detail" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="detail">
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" />
</xs:complexType>
</xs:schema>

View File

@ -1,188 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS's procedures with respect to rights in OASIS specifications can be found at the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementors or users of this specification, can be obtained from the OASIS Executive Director.
OASIS invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights which may cover technology that may be required to implement this specification. Please address the information to the OASIS Executive Director.
Copyright (C) OASIS Open (2004-2006). All Rights Reserved.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to OASIS, except as needed for the purpose of developing OASIS specifications, in which case the procedures for copyrights defined in the OASIS Intellectual Property Rights document must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
-->
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wstop = "http://docs.oasis-open.org/wsn/t-1"
targetNamespace = "http://docs.oasis-open.org/wsn/t-1"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<!-- =============== utility type definitions ==================== -->
<xsd:complexType name="Documentation" mixed="true">
<xsd:sequence>
<xsd:any processContents="lax" minOccurs="0"
maxOccurs="unbounded" namespace="##any"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ExtensibleDocumented" abstract="true"
mixed="false">
<xsd:sequence>
<xsd:element name="documentation" type="wstop:Documentation"
minOccurs="0" />
</xsd:sequence>
<xsd:anyAttribute namespace="##other" processContents="lax" />
</xsd:complexType>
<xsd:complexType name="QueryExpressionType" mixed="true">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="1" processContents="lax" />
</xsd:sequence>
<xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
</xsd:complexType>
<!-- ================== Topic-Namespace Related ================ -->
<xsd:complexType name="TopicNamespaceType">
<xsd:complexContent>
<xsd:extension base="wstop:ExtensibleDocumented">
<xsd:sequence>
<xsd:element name="Topic"
minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="wstop:TopicType">
<xsd:attribute name="parent" type="wstop:ConcreteTopicExpression" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:any namespace="##other"
minOccurs="0" maxOccurs="unbounded"
processContents="lax"/>
</xsd:sequence>
<xsd:attribute name="name" type="xsd:NCName"/>
<xsd:attribute name="targetNamespace" type="xsd:anyURI"
use="required"/>
<xsd:attribute name="final" type="xsd:boolean"
default="false"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="TopicNamespace" type="wstop:TopicNamespaceType">
<xsd:unique name="rootTopicUniqueness">
<xsd:selector xpath="wstop:Topic"/>
<xsd:field xpath="@name"/>
</xsd:unique>
</xsd:element>
<xsd:attribute name="topicNamespaceLocation" type="xsd:anyURI"/>
<!-- ===================== Topic Related ========================= -->
<xsd:complexType name="TopicType">
<xsd:complexContent>
<xsd:extension base="wstop:ExtensibleDocumented">
<xsd:sequence>
<xsd:element name="MessagePattern"
type="wstop:QueryExpressionType"
minOccurs="0" maxOccurs="1" />
<xsd:any minOccurs="0"/>
<!-- <xsd:element name="Topic" type="wstop:TopicType"
minOccurs="0" maxOccurs="unbounded">
<xsd:unique name="childTopicUniqueness">
<xsd:selector xpath="wstop:topic"/>
<xsd:field xpath="@name"/>
</xsd:unique>
</xsd:element> -->
<xsd:any namespace="##other" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:NCName"/>
<!--
<xsd:attribute name="messageTypes">
<xsd:simpleType>
<xsd:list itemType="xsd:QName"/>
</xsd:simpleType>
</xsd:attribute>
-->
<xsd:attribute name="final" type="xsd:boolean"
default="false"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- ================ Topic Set Related =================== -->
<xsd:complexType name="TopicSetType">
<xsd:complexContent>
<xsd:extension base="wstop:ExtensibleDocumented">
<xsd:sequence>
<xsd:any namespace="##other"
minOccurs="0" maxOccurs="unbounded"
processContents="lax"/>
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<xsd:element name="TopicSet" type="wstop:TopicSetType"/>
<xsd:attribute name="topic" type="xsd:boolean" default="false"/>
<!-- ================ Topic Expression Related =================== -->
<xsd:simpleType name="FullTopicExpression">
<xsd:restriction base="xsd:token">
<xsd:annotation>
<xsd:documentation>
TopicPathExpression ::= TopicPath ( '|' TopicPath )*
TopicPath ::= RootTopic ChildTopicExpression*
RootTopic ::= NamespacePrefix? ('//')? (NCName | '*')
NamespacePrefix ::= NCName ':'
ChildTopicExpression ::= '/' '/'? (QName | NCName | '*'| '.')
</xsd:documentation>
</xsd:annotation>
<xsd:pattern value=
"([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*(\|([\i-[:]][\c-[:]]*:)?(//)?([\i-[:]][\c-[:]]*|\*)((/|//)(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*|\*|[.]))*)*">
</xsd:pattern>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ConcreteTopicExpression">
<xsd:restriction base="xsd:token">
<xsd:annotation>
<xsd:documentation>
The pattern allows strings matching the following EBNF:
ConcreteTopicPath ::= RootTopic ChildTopic*
RootTopic ::= QName
ChildTopic ::= '/' (QName | NCName)
</xsd:documentation>
</xsd:annotation>
<xsd:pattern value=
"(([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)(/([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*)*" >
</xsd:pattern>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="SimpleTopicExpression">
<xsd:restriction base="xsd:QName">
<xsd:annotation>
<xsd:documentation>
The pattern allows strings matching the following EBNF:
RootTopic ::= QName
</xsd:documentation>
</xsd:annotation>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

View File

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) OASIS(r) 2009. All Rights Reserved.
All capitalized terms in the following text have the meanings assigned to them in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at the OASIS website.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to OASIS, except as needed for the purpose of developing any document or deliverable produced by an OASIS Technical Committee (in which case the rules applicable to copyrights, as set forth in the OASIS IPR Policy, must be followed) or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
OASIS requests that any OASIS Party or any other party that believes it has patent claims that would necessarily be infringed by implementations of this OASIS Committee Specification or OASIS Standard, to notify OASIS TC Administrator and provide an indication of its willingness to grant patent licenses to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification.
OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of ownership of any patent claims that would necessarily be infringed by implementations of this specification by a patent holder that is not willing to provide a license to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification. OASIS may include such claims on its website, but disclaims any obligation to do so.
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS' procedures with respect to rights in any document or deliverable produced by an OASIS Technical Committee can be found on the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this OASIS Committee Specification or OASIS Standard, can be obtained from the OASIS TC Administrator. OASIS makes no representation that any information or list of intellectual property rights will at any time be complete, or that any claims in such list are, in fact, Essential Claims.
The name "OASIS" is trademarks of OASIS, the owner and developer of this specification, and should be used only to refer to the organization and its official outputs. OASIS welcomes reference to, and implementation and use of, specifications, while reserving the right to enforce its marks against misleading uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.
-->
<xs:schema
targetNamespace="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
xmlns:tns="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
blockDefault="#all" >
<xs:import
namespace="http://www.w3.org/2005/08/addressing"
schemaLocation="http://www.w3.org/2006/03/addressing/ws-addr.xsd" />
<!-- //////////////////// Discovery Messages //////////////////// -->
<xs:element name="Hello" type="tns:HelloType" />
<xs:complexType name="HelloType" >
<xs:sequence>
<xs:element ref="wsa:EndpointReference" />
<xs:element ref="tns:Types" minOccurs="0" />
<xs:element ref="tns:Scopes" minOccurs="0" />
<xs:element ref="tns:XAddrs" minOccurs="0" />
<xs:element ref="tns:MetadataVersion" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Bye" type="tns:ByeType" />
<xs:complexType name="ByeType" >
<xs:sequence>
<xs:element ref="wsa:EndpointReference" />
<xs:element ref="tns:Types" minOccurs="0" />
<xs:element ref="tns:Scopes" minOccurs="0" />
<xs:element ref="tns:XAddrs" minOccurs="0" />
<xs:element ref="tns:MetadataVersion" minOccurs="0" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Probe" type="tns:ProbeType" />
<xs:complexType name="ProbeType" >
<xs:sequence>
<xs:element ref="tns:Types" minOccurs="0" />
<xs:element ref="tns:Scopes" minOccurs="0" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="ProbeMatches" type="tns:ProbeMatchesType" />
<xs:complexType name="ProbeMatchesType" >
<xs:sequence>
<xs:element name="ProbeMatch"
type="tns:ProbeMatchType"
minOccurs="0"
maxOccurs="unbounded" >
</xs:element>
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:complexType name="ProbeMatchType" >
<xs:sequence>
<xs:element ref="wsa:EndpointReference" />
<xs:element ref="tns:Types" minOccurs="0" />
<xs:element ref="tns:Scopes" minOccurs="0" />
<xs:element ref="tns:XAddrs" minOccurs="0" />
<xs:element ref="tns:MetadataVersion" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Resolve" type="tns:ResolveType" />
<xs:complexType name="ResolveType" >
<xs:sequence>
<xs:element ref="wsa:EndpointReference" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="ResolveMatches" type="tns:ResolveMatchesType" />
<xs:complexType name="ResolveMatchesType" >
<xs:sequence>
<xs:element name="ResolveMatch"
type="tns:ResolveMatchType"
minOccurs="0" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:complexType name="ResolveMatchType" >
<xs:sequence>
<xs:element ref="wsa:EndpointReference" />
<xs:element ref="tns:Types" minOccurs="0" />
<xs:element ref="tns:Scopes" minOccurs="0" />
<xs:element ref="tns:XAddrs" minOccurs="0" />
<xs:element ref="tns:MetadataVersion" />
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Types" type="tns:QNameListType" />
<xs:simpleType name="QNameListType" >
<xs:list itemType="xs:QName" />
</xs:simpleType>
<xs:element name="Scopes" type="tns:ScopesType" />
<xs:complexType name="ScopesType" >
<xs:simpleContent>
<xs:extension base="tns:UriListType" >
<xs:attribute name="MatchBy" type="xs:anyURI" />
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="XAddrs" type="tns:UriListType" />
<xs:simpleType name="UriListType" >
<xs:list itemType="xs:anyURI" />
</xs:simpleType>
<xs:element name="MetadataVersion" type="xs:unsignedInt" />
<!-- //////////////////// Faults //////////////////// -->
<xs:simpleType name="FaultCodeType" >
<xs:restriction base="xs:QName" >
<xs:enumeration value="tns:MatchingRuleNotSupported" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="FaultCodeOpenType" >
<xs:union memberTypes="tns:FaultCodeType xs:QName" />
</xs:simpleType>
<xs:element name="SupportedMatchingRules" type="tns:UriListType" />
<!-- //////////////////// Compact Signature //////////////////// -->
<xs:attribute name="Id" type="xs:ID"/>
<xs:element name="Security" type="tns:SecurityType" />
<xs:complexType name="SecurityType" >
<xs:sequence>
<xs:element ref="tns:Sig" minOccurs="0" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Sig" type="tns:SigType" />
<xs:complexType name="SigType" >
<xs:sequence>
<xs:any namespace="##other"
processContents="lax"
minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Scheme" type="xs:anyURI" use="required" />
<xs:attribute name="KeyId" type="xs:base64Binary" />
<xs:attribute name="Refs" type="xs:IDREFS" use="required" />
<xs:attribute name="Sig" type="xs:base64Binary" use="required" />
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<!-- //////////////////// General Headers //////////////////// -->
<xs:element name="AppSequence" type="tns:AppSequenceType" />
<xs:complexType name="AppSequenceType" >
<xs:complexContent>
<xs:restriction base="xs:anyType" >
<xs:attribute name="InstanceId"
type="xs:unsignedInt"
use="required" />
<xs:attribute name="SequenceId" type="xs:anyURI" />
<xs:attribute name="MessageNumber"
type="xs:unsignedInt"
use="required" />
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View File

@ -1,137 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) OASIS(r) 2009. All Rights Reserved.
All capitalized terms in the following text have the meanings assigned to them in the OASIS Intellectual Property Rights Policy (the "OASIS IPR Policy"). The full Policy may be found at the OASIS website.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published, and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this section are included on all such copies and derivative works. However, this document itself may not be modified in any way, including by removing the copyright notice or references to OASIS, except as needed for the purpose of developing any document or deliverable produced by an OASIS Technical Committee (in which case the rules applicable to copyrights, as set forth in the OASIS IPR Policy, must be followed) or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by OASIS or its successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and OASIS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY OWNERSHIP RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
OASIS requests that any OASIS Party or any other party that believes it has patent claims that would necessarily be infringed by implementations of this OASIS Committee Specification or OASIS Standard, to notify OASIS TC Administrator and provide an indication of its willingness to grant patent licenses to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification.
OASIS invites any party to contact the OASIS TC Administrator if it is aware of a claim of ownership of any patent claims that would necessarily be infringed by implementations of this specification by a patent holder that is not willing to provide a license to such patent claims in a manner consistent with the IPR Mode of the OASIS Technical Committee that produced this specification. OASIS may include such claims on its website, but disclaims any obligation to do so.
OASIS takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on OASIS' procedures with respect to rights in any document or deliverable produced by an OASIS Technical Committee can be found on the OASIS website. Copies of claims of rights made available for publication and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this OASIS Committee Specification or OASIS Standard, can be obtained from the OASIS TC Administrator. OASIS makes no representation that any information or list of intellectual property rights will at any time be complete, or that any claims in such list are, in fact, Essential Claims.
The name "OASIS" is trademarks of OASIS, the owner and developer of this specification, and should be used only to refer to the organization and its official outputs. OASIS welcomes reference to, and implementation and use of, specifications, while reserving the right to enforce its marks against misleading uses. Please see http://www.oasis-open.org/who/trademark.php for above guidance.
-->
<wsdl:definitions
targetNamespace="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
xmlns:tns="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<wsdl:types>
<xs:schema>
<xs:import
namespace="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
schemaLocation="http://docs.oasis-open.org/ws-dd/discovery/1.1/os/wsdd-discovery-1.1-schema-os.xsd" />
</xs:schema>
</wsdl:types>
<wsdl:message name="HelloMessage" >
<wsdl:part name="parameters" element="tns:Hello" />
</wsdl:message>
<wsdl:message name="ByeMessage" >
<wsdl:part name="parameters" element="tns:Bye" />
</wsdl:message>
<wsdl:message name="ProbeMessage" >
<wsdl:part name="parameters" element="tns:Probe" />
</wsdl:message>
<wsdl:message name="ProbeMatchMessage" >
<wsdl:part name="parameters" element="tns:ProbeMatches" />
</wsdl:message>
<wsdl:message name="ResolveMessage" >
<wsdl:part name="parameters" element="tns:Resolve" />
</wsdl:message>
<wsdl:message name="ResolveMatchMessage" >
<wsdl:part name="parameters" element="tns:ResolveMatches" />
</wsdl:message>
<wsdl:portType name="TargetService" >
<wsdl:operation name="HelloOp" >
<wsdl:output message="tns:HelloMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Hello"
/>
</wsdl:operation>
<wsdl:operation name="ByeOp" >
<wsdl:output message="tns:ByeMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Bye"
/>
</wsdl:operation>
<wsdl:operation name="ProbeOp" >
<wsdl:input message="tns:ProbeMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Probe"
/>
</wsdl:operation>
<wsdl:operation name="ProbeMatchOp" >
<wsdl:output message="tns:ProbeMatchMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ProbeMatches"
/>
</wsdl:operation>
<wsdl:operation name="ResolveOp" >
<wsdl:input message="tns:ResolveMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Resolve"
/>
</wsdl:operation>
<wsdl:operation name="ResolveMatchOp" >
<wsdl:output message="tns:ResolveMatchMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ResolveMatches"
/>
</wsdl:operation>
</wsdl:portType>
<!-- If this portType is included in Types, it indicates the
Target Service is a Discovery Proxy operating in a managed mode.
Discovery Proxies also implement tns:TargetService in an ad hoc mode.
-->
<wsdl:portType name="DiscoveryProxy">
<wsdl:operation name="HelloOp" >
<wsdl:input message="tns:HelloMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Hello"
/>
</wsdl:operation>
<wsdl:operation name="ByeOp" >
<wsdl:input message="tns:ByeMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Bye"
/>
</wsdl:operation>
<wsdl:operation name="ProbeOp" >
<wsdl:input message="tns:ProbeMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Probe"
/>
<wsdl:output message="tns:ProbeMatchMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ProbeMatches"
/>
</wsdl:operation>
<wsdl:operation name="ResolveOp" >
<wsdl:input message="tns:ResolveMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Resolve"
/>
<wsdl:output message="tns:ResolveMatchMessage"
wsaw:Action
="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/ResolveMatches"
/>
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" ?>
<wsdl:definitions targetNamespace="http://127.0.0.1"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdd="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
xmlns:local="http://127.0.0.1">
<wsdl:import namespace="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01"
location="http://docs.oasis-open.org/ws-dd/discovery/1.1/os/wsdd-discovery-1.1-wsdl-os.wsdl"/>
<!--===============================-->
<wsdl:binding name="WSDiscoveryBinding" type="wsdd:DiscoveryProxy">
<soap:binding style="document" transport="http://docs.oasis-open.org/ws-dd/soapoverudp/1.1"/>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<wsdl:operation name="ProbeOp">
<soap:operation soapAction="http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Probe"/>
<wsdl:input>
<!-- <soap:header -->
<soap:body parts="parameters" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body parts="parameters" use="literal"/>
</wsdl:output>
</wsdl:operation>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
</wsdl:binding>
<!--===============================-->
<wsdl:service name="WSDiscovery">
<wsdl:port name="WSDiscoveryPort" binding="local:WSDiscoveryBinding" >
<soap:address
location="soap.udp://239.255.255.250:3702/" />
</wsdl:port>
</wsdl:service>
<!--===============================-->
</wsdl:definitions>

View File

@ -1,314 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2001 - 2005, International Business Machines Corporation and Microsoft Corporation
All Rights Reserved
License for WSDL Schema Files
The Authors grant permission to copy and distribute the WSDL Schema
Files in any medium without fee or royalty as long as this notice and
license are distributed with them. The originals of these files can
be located at:
http://schemas.xmlsoap.org/wsdl/2003-02-11.xsd
THESE SCHEMA FILES ARE PROVIDED "AS IS," AND THE AUTHORS MAKE NO REPRESENTATIONS
OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THESE FILES, INCLUDING, BUT NOT
LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
NON-INFRINGEMENT OR TITLE. THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT,
INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR
RELATING TO ANY USE OR DISTRIBUTION OF THESE FILES.
The name and trademarks of the Authors may NOT be used in any manner,
including advertising or publicity pertaining to these files or any program
or service that uses these files, written prior permission. Title to copyright
in these files will at all times remain with the Authors.
No other rights are granted by implication, estoppel or otherwise.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://schemas.xmlsoap.org/wsdl/"
elementFormDefault="qualified" >
<xs:complexType mixed="true" name="tDocumentation" >
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="tDocumented" >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow them to be documented
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="documentation" type="wsdl:tDocumentation" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="tExtensibleAttributesDocumented" abstract="true" >
<xs:complexContent>
<xs:extension base="wsdl:tDocumented" >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow attributes from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tExtensibleDocumented" abstract="true" >
<xs:complexContent>
<xs:extension base="wsdl:tDocumented" >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow elements from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="definitions" type="wsdl:tDefinitions" >
<xs:key name="message" >
<xs:selector xpath="wsdl:message" />
<xs:field xpath="@name" />
</xs:key>
<xs:key name="portType" >
<xs:selector xpath="wsdl:portType" />
<xs:field xpath="@name" />
</xs:key>
<xs:key name="binding" >
<xs:selector xpath="wsdl:binding" />
<xs:field xpath="@name" />
</xs:key>
<xs:key name="service" >
<xs:selector xpath="wsdl:service" />
<xs:field xpath="@name" />
</xs:key>
<xs:key name="import" >
<xs:selector xpath="wsdl:import" />
<xs:field xpath="@namespace" />
</xs:key>
</xs:element>
<xs:group name="anyTopLevelOptionalElement" >
<xs:annotation>
<xs:documentation>
Any top level optional element allowed to appear more then once - any child of definitions element except wsdl:types. Any extensibility element is allowed in any place.
</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:element name="import" type="wsdl:tImport" />
<xs:element name="types" type="wsdl:tTypes" />
<xs:element name="message" type="wsdl:tMessage" >
<!--
<xs:unique name="part" >
<xs:selector xpath="wsdl:part" />
<xs:field xpath="@name" />
</xs:unique>
-->
</xs:element>
<xs:element name="portType" type="wsdl:tPortType" />
<xs:element name="binding" type="wsdl:tBinding" />
<xs:element name="service" type="wsdl:tService" >
<!--
<xs:unique name="port" >
<xs:selector xpath="wsdl:port" />
<xs:field xpath="@name" />
</xs:unique>
-->
</xs:element>
</xs:choice>
</xs:group>
<xs:complexType name="tDefinitions" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:group ref="wsdl:anyTopLevelOptionalElement" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="targetNamespace" type="xs:anyURI" use="optional" />
<xs:attribute name="name" type="xs:NCName" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tImport" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented" >
<xs:attribute name="namespace" type="xs:anyURI" use="required" />
<xs:attribute name="location" type="xs:anyURI" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tTypes" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tMessage" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:element name="part" type="wsdl:tPart" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tPart" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented" >
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="element" type="xs:QName" use="optional" />
<xs:attribute name="type" type="xs:QName" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tPortType" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented" >
<xs:sequence>
<xs:element name="operation" type="wsdl:tOperation" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tOperation" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:choice>
<xs:group ref="wsdl:request-response-or-one-way-operation" />
<xs:group ref="wsdl:solicit-response-or-notification-operation" />
</xs:choice>
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="parameterOrder" type="xs:NMTOKENS" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:group name="request-response-or-one-way-operation" >
<xs:sequence>
<xs:element name="input" type="wsdl:tParam" />
<xs:sequence minOccurs='0' >
<xs:element name="output" type="wsdl:tParam" />
<xs:element name="fault" type="wsdl:tFault" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:group name="solicit-response-or-notification-operation" >
<xs:sequence>
<xs:element name="output" type="wsdl:tParam" />
<xs:sequence minOccurs='0' >
<xs:element name="input" type="wsdl:tParam" />
<xs:element name="fault" type="wsdl:tFault" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:complexType name="tParam" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented" >
<xs:attribute name="name" type="xs:NCName" use="optional" />
<xs:attribute name="message" type="xs:QName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tFault" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleAttributesDocumented" >
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="message" type="xs:QName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tBinding" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:element name="operation" type="wsdl:tBindingOperation" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="type" type="xs:QName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tBindingOperationMessage" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:attribute name="name" type="xs:NCName" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tBindingOperationFault" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tBindingOperation" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:element name="input" type="wsdl:tBindingOperationMessage" minOccurs="0" />
<xs:element name="output" type="wsdl:tBindingOperationMessage" minOccurs="0" />
<xs:element name="fault" type="wsdl:tBindingOperationFault" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tService" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:sequence>
<xs:element name="port" type="wsdl:tPort" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tPort" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibleDocumented" >
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="binding" type="xs:QName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:attribute name="arrayType" type="xs:string" />
<xs:attribute name="required" type="xs:boolean" />
<xs:complexType name="tExtensibilityElement" abstract="true" >
<xs:attribute ref="wsdl:required" use="optional" />
</xs:complexType>
</xs:schema>

View File

@ -1,143 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
Copyright 2001 - 2006, International Business Machines Corporation and Microsoft Corporation
All Rights Reserved
License for WSDL 1.1 Binding Extension for SOAP 1.2 Schema Files
The Authors grant permission to copy and distribute the WSDL 1.1 Binding Extension for SOAP 1.2 Schema Files in any medium without fee or royalty as long as this notice and license are distributed with them. The originals of these files can be located at:
http://schemas.xmlsoap.org/wsdl/soap12/wsdl11soap12.xsd
THESE SCHEMA FILES ARE PROVIDED "AS IS," AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THESE FILES, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT OR TITLE. THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY USE OR DISTRIBUTION OF THESE FILES.
The name and trademarks of the Authors may NOT be used in any manner, including advertising or publicity pertaining to these files or any program or service that uses these files, written prior permission. Title to copyright in these files will at all times remain with the Authors.
No other rights are granted by implication, estoppel or otherwise.
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsoap12="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace="http://schemas.xmlsoap.org/wsdl/soap12/" >
<xs:import namespace = "http://schemas.xmlsoap.org/wsdl/" />
<xs:complexType name="tExtensibilityElementOpenAttrs" >
<xs:complexContent>
<xs:extension base="wsdl:tExtensibilityElement" >
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="binding" type="wsoap12:tBinding" />
<xs:complexType name="tBinding" >
<xs:complexContent>
<xs:extension base="wsoap12:tExtensibilityElementOpenAttrs" >
<xs:attribute name="transport" type="xs:anyURI" use="required" />
<xs:attribute name="style" type="wsoap12:tStyleChoice" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="tStyleChoice" >
<xs:restriction base="xs:string" >
<xs:enumeration value="rpc" />
<xs:enumeration value="document" />
</xs:restriction>
</xs:simpleType>
<xs:element name="operation" type="wsoap12:tOperation" />
<xs:complexType name="tOperation" >
<xs:complexContent>
<xs:extension base="wsoap12:tExtensibilityElementOpenAttrs" >
<xs:attribute name="soapAction" type="xs:anyURI" use="optional" />
<xs:attribute name="soapActionRequired" type="xs:boolean" use="optional" />
<xs:attribute name="style" type="wsoap12:tStyleChoice" use="optional" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="body" type="wsoap12:tBody" />
<xs:attributeGroup name="tBodyAttributes" >
<!-- The encodingStyle attribute is now a single URI, instead of a list of URIs -->
<xs:attribute name="encodingStyle" type="xs:anyURI" use="optional" />
<xs:attribute name="use" type="wsoap12:useChoice" use="optional" />
<xs:attribute name="namespace" type="xs:anyURI" use="optional" />
</xs:attributeGroup>
<xs:simpleType name="tParts">
<xs:list itemType="xs:NMTOKEN"/>
</xs:simpleType>
<xs:complexType name="tBody" >
<xs:complexContent>
<xs:extension base="wsoap12:tExtensibilityElementOpenAttrs" >
<xs:attribute name="parts" type="wsoap12:tParts" use="optional" />
<xs:attributeGroup ref = "wsoap12:tBodyAttributes" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name="useChoice" >
<xs:restriction base="xs:string" >
<xs:enumeration value="literal" />
<xs:enumeration value="encoded" />
</xs:restriction>
</xs:simpleType>
<xs:element name="fault" type="wsoap12:tFault" />
<xs:complexType name="tFaultRes" abstract="true" >
<xs:complexContent>
<xs:restriction base="wsoap12:tBody" >
<xs:attribute ref="wsdl:required" use="optional" />
<xs:attribute name="parts" type="wsoap12:tParts" use="prohibited" />
<xs:attributeGroup ref="wsoap12:tBodyAttributes" />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="tFault" >
<xs:complexContent>
<xs:extension base="wsoap12:tFaultRes">
<xs:attribute name="name" type="xs:NCName" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="header" type="wsoap12:tHeader" />
<xs:attributeGroup name="tHeaderAttributes" >
<xs:attribute name="message" type="xs:QName" use="required" />
<xs:attribute name="part" type="xs:NMTOKEN" use="required" />
<xs:attribute name="use" type="wsoap12:useChoice" use="required" />
<xs:attribute name="encodingStyle" type="xs:anyURI" use="optional" />
<xs:attribute name="namespace" type="xs:anyURI" use="optional" />
</xs:attributeGroup>
<xs:complexType name="tHeader" >
<xs:complexContent>
<xs:extension base="wsoap12:tExtensibilityElementOpenAttrs" >
<xs:sequence>
<xs:element ref="wsoap12:headerfault" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attributeGroup ref="wsoap12:tHeaderAttributes" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="headerfault" type="wsoap12:tHeaderFault" />
<xs:complexType name="tHeaderFault" >
<xs:attributeGroup ref="wsoap12:tHeaderAttributes" />
<xs:anyAttribute namespace="##other" processContents="lax"/>
</xs:complexType>
<xs:element name="address" type="wsoap12:tAddress" />
<xs:complexType name="tAddress" >
<xs:complexContent>
<xs:extension base="wsoap12:tExtensibilityElementOpenAttrs" >
<xs:attribute name="location" type="xs:anyURI" use="required" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>

View File

@ -1,49 +0,0 @@
<?xml version="1.0" ?>
<!--
W3C XML Schema defined in the Describing Media Content of Binary Data in XML
specification
http://www.w3.org/TR/xml-media-types
Copyright © 2005 World Wide Web Consortium,
(Massachusetts Institute of Technology, European Research Consortium for
Informatics and Mathematics, Keio University). All Rights Reserved. This
work is distributed under the W3C® Software License [1] in the hope that
it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
$Id: xmlmime.xsd,v 1.1 2005/04/25 17:08:35 hugo Exp $
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
targetNamespace="http://www.w3.org/2005/05/xmlmime" >
<xs:attribute name="contentType">
<xs:simpleType>
<xs:restriction base="xs:string" >
<xs:minLength value="3" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="expectedContentTypes" type="xs:string" />
<xs:complexType name="base64Binary" >
<xs:simpleContent>
<xs:extension base="xs:base64Binary" >
<xs:attribute ref="xmime:contentType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="hexBinary" >
<xs:simpleContent>
<xs:extension base="xs:hexBinary" >
<xs:attribute ref="xmime:contentType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>

View File

@ -1,13 +0,0 @@
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:tns='http://www.w3.org/2004/08/xop/include'
targetNamespace='http://www.w3.org/2004/08/xop/include' >
<xs:element name='Include' type='tns:Include' />
<xs:complexType name='Include' >
<xs:sequence>
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='href' type='xs:anyURI' use='required' />
<xs:anyAttribute namespace='##other' />
</xs:complexType>
</xs:schema>

View File

@ -16,6 +16,7 @@ configure_file(zmvideo.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" @ONLY)
configure_file(zmwatch.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" @ONLY) configure_file(zmwatch.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" @ONLY)
configure_file(zmcamtool.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" @ONLY) configure_file(zmcamtool.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" @ONLY)
configure_file(zmsystemctl.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" @ONLY) configure_file(zmsystemctl.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" @ONLY)
configure_file(zmtelemetry.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" @ONLY)
if(NOT ZM_NO_X10) if(NOT ZM_NO_X10)
configure_file(zmx10.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" @ONLY) configure_file(zmx10.pl.in "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" @ONLY)
endif(NOT ZM_NO_X10) endif(NOT ZM_NO_X10)
@ -31,7 +32,7 @@ FOREACH(PERLSCRIPT ${perlscripts})
ENDFOREACH(PERLSCRIPT ${perlscripts}) ENDFOREACH(PERLSCRIPT ${perlscripts})
# Install the perl scripts # Install the perl scripts
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmaudit.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcontrol.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmdc.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmfilter.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmpkg.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrack.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtrigger.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmupdate.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmvideo.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmwatch.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmcamtool.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmsystemctl.pl" "${CMAKE_CURRENT_BINARY_DIR}/zmtelemetry.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
if(NOT ZM_NO_X10) if(NOT ZM_NO_X10)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zmx10.pl" DESTINATION "${CMAKE_INSTALL_FULL_BINDIR}" PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif(NOT ZM_NO_X10) endif(NOT ZM_NO_X10)

View File

@ -1985,7 +1985,7 @@ our @options =
You can use filters to instruct ZoneMinder to upload events to You can use filters to instruct ZoneMinder to upload events to
a remote server. This option indicates the password that a remote server. This option indicates the password that
ZoneMinder should use to log in for transfer. If you are using ZoneMinder should use to log in for transfer. If you are using
certicate based logins for SFTP servers you can leave this certificate based logins for SFTP servers you can leave this
option blank. option blank.
"), "),
requires => [ { name => "ZM_OPT_UPLOAD", value => "yes" } ], requires => [ { name => "ZM_OPT_UPLOAD", value => "yes" } ],
@ -2077,6 +2077,21 @@ our @options =
type => $types{integer}, type => $types{integer},
category => "upload", category => "upload",
}, },
{
name => "ZM_UPLOAD_STRICT",
default => "no",
description => "Require strict host key checking for SFTP uploads",
help => qqq("
You can require SFTP uploads to verify the host key of the remote server
for protection against man-in-the-middle attacks. You will need to add the
server's key to the known_hosts file. On most systems, this will be
~/.ssh/known_hosts, where ~ is the home directory of the web server running
ZoneMinder.
"),
requires => [ { name => "ZM_OPT_UPLOAD", value => "yes" } ],
type => $types{boolean},
category => "upload",
},
{ {
name => "ZM_UPLOAD_FTP_PASSIVE", name => "ZM_UPLOAD_FTP_PASSIVE",
default => "yes", default => "yes",
@ -2731,6 +2746,44 @@ body = "ZM alarm detected - %EL% secs, %EF%/%EFA% frames, t%EST%/m%ESM%/a%ESA% s
type => $types{boolean}, type => $types{boolean},
category => "system", category => "system",
}, },
{
name => "ZM_TELEMETRY_DATA",
default => "yes",
description => "Send usage information to ZoneMinder",
help => qqq("
Enable collection of usage information of the local system and send
it to the ZoneMinder development team. This data will be used to
determine things like who and where our customers are, how big their
systems are, the underlying hardware and operating system, etc.
This is being done for the sole purpoase of creating a better
product for our target audience. This script is intended to be
completely transparent to the end user, and can be disabled from
the web console under Options.
"),
type => $types{boolean},
category => "system",
},
{
name => "ZM_TELEMETRY_UUID",
default => "",
description => "Unique identifier for ZoneMinder telemetry",
help => qqq("
This variable is auto-generated once by the system and is used to
uniquely identify it among all other ZoneMinder systems in
existence.
"),
type => $types{string},
category => "dynamic",
},
{
name => "ZM_TELEMETRY_LAST_UPLOAD",
default => "",
description => "When the last ZoneMinder telemetry upload ocurred",
help => "",
type => $types{integer},
readonly => 1,
category => "dynamic",
},
{ {
name => "ZM_UPDATE_CHECK_PROXY", name => "ZM_UPDATE_CHECK_PROXY",
default => "", default => "",

View File

@ -155,7 +155,7 @@ sub reset
#my $cmd = "setOSDSetting%26isEnableTimeStamp%3D0%26isEnableDevName%3D1%26dispPos%3D0%26isEnabledOSDMask%3D0"; #my $cmd = "setOSDSetting%26isEnableTimeStamp%3D0%26isEnableDevName%3D1%26dispPos%3D0%26isEnabledOSDMask%3D0";
Info ("Sending reboot $cmd"); Info ("Sending reboot $cmd");
$self->sendCmd( $cmd ); $self->sendCmd( $cmd );
# Setup For Stream=0 Resolution=720p Bandwith=4M FPS=30 KeyFrameInterval/GOP=100 VBR=ON # Setup For Stream=0 Resolution=720p Bandwidth=4M FPS=30 KeyFrameInterval/GOP=100 VBR=ON
#$cmd = "setVideoStreamParam%26streamType%3D0%26resolution%3D0%26bitRate%3D4194304%26frameRate%3D30%26GOP%3D100%26isVBR%3D1"; #$cmd = "setVideoStreamParam%26streamType%3D0%26resolution%3D0%26bitRate%3D4194304%26frameRate%3D30%26GOP%3D100%26isVBR%3D1";
#$self->sendCmd( $cmd ); #$self->sendCmd( $cmd );
# Setup For Infrared AUTO # Setup For Infrared AUTO

View File

@ -0,0 +1,377 @@
# ==========================================================================
#
# ZoneMinder IPCC-7210W IP Control Protocol Module, $Date: 2015-11-18$, $Revision: 0001$
# Modified for use with IPCC-7210W on Nov 2015
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the
# IPCC-7210W IP camera control protocol
#
package ZoneMinder::Control::IPCC-7210W;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
# ==========================================================================
#
# IPCC-7210W IP Control Protocol
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
#print( "http://$address/$cmd\n" );
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} );
Info( "http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
}
return( $result );
}
sub cameraReset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "reboot.cgi?";
$self->sendCmd( $cmd );
}
#Up Arrow
sub moveConUp
{
my $self = shift;
my $params = shift;
Debug( "Move Up" );
my $cmd = "decoder_control.cgi?command=0&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Down Arrow
sub moveConDown
{
my $self = shift;
my $params = shift;
Debug( "Move Down" );
my $cmd = "decoder_control.cgi?command=2&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Left Arrow
sub moveConLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Left" );
my $cmd = "decoder_control.cgi?command=4&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Right Arrow
sub moveConRight
{
my $self = shift;
my $params = shift;
Debug( "Move Right" );
my $cmd = "decoder_control.cgi?command=6&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Up Right Arrow
sub moveConUpRight
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Up Right" );
my $cmd = "decoder_control.cgi?command=91&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Down Right Arrow
sub moveConDownRight
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Down Right" );
my $cmd = "decoder_control.cgi?command=93&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Up Left Arrow
sub moveConUpLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Up Left" );
my $cmd = "decoder_control.cgi?command=90&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Down Left Arrow
sub moveConDownLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Down Left" );
my $cmd = "decoder_control.cgi?command=92&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Stop
sub moveStop
{
my $self = shift;
Debug( "Move Stop" );
my $cmd = "decoder_control.cgi?command=1&onestep=1&";
$self->sendCmd( $cmd );
}
#Move Camera to Home Position
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "decoder_control.cgi?command=25&onestep=0&";
$self->sendCmd( $cmd );
}
# zoom out
sub zoomRelTele
{
my $self = shift;
Debug( "Zoom Tele" );
my $cmd = "camera_control.cgi?param=17&value=1&";
$self->sendCmd( $cmd );
}
#zoom in
sub zoomRelWide
{
my $self = shift;
Debug( "Zoom Wide" );
my $cmd = "camera_control.cgi?param=18&value=1&";
$self->sendCmd( $cmd );
}
#Set preset
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
my $presetCmd = 30 + (($preset-1)*2);
Debug( "Set Preset $preset with cmd $presetCmd" );
my $cmd = "decoder_control.cgi?command=$presetCmd&onestep=0&sit=$presetCmd&";
$self->sendCmd( $cmd );
}
#Goto preset
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
my $presetCmd = 31 + (($preset-1)*2);
Debug( "Goto Preset $preset with cmd $presetCmd" );
my $cmd = "decoder_control.cgi?command=$presetCmd&onestep=0&sit=$presetCmd&";
$self->sendCmd( $cmd );
}
#Turn IR on
sub wake
{
my $self = shift;
Debug( "Wake - IR on" );
my $cmd = "camera_control.cgi?param=14&value=1&";
$self->sendCmd( $cmd );
}
#Turn IR off
sub sleep
{
my $self = shift;
Debug( "Sleep - IR off" );
my $cmd = "camera_control.cgi?param=14&value=0&";
$self->sendCmd( $cmd );
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
ZoneMinder::IPCC-7210W - Perl extension for IPCC-7210W PTZ control
=head1 SYNOPSIS
use ZoneMinder::Control::IPCC
=head1 DESCRIPTION
This script provides Pan/Tilt/Zoom control for IPCC-7210W camera.
=head1 SEE ALSO
ZoneMinder::Control::Wanscam
=head1 AUTHOR
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2008
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -0,0 +1,483 @@
# ==========================================================================
#
# ZoneMinder Netcat IP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0001 $
# Copyright (C) 2001-2008 Philip Coombes
# Converted for use with Netcat IP Camera by Andrew Bauer (knnniggett@users.sourceforge.net)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the first implementation of the Netcat IP camera control
# protocol
#
package ZoneMinder::Control::Netcat;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
our %CamParams = ();
# ==========================================================================
#
# Netcat IP Control Protocol
# This script sends ONVIF compliant commands and may work with other cameras
#
# The Netcat camera gladly accepts any command with or without authentication,
# which prevented me from developing Onvif authentication in this control script.
#
# Basic preset functions are supported, but more advanced features, which make
# use of abnormally high preset numbers (ir lamp control, tours, pan speed, etc)
# may or may not work.
#
#
# Possible future improvements (for anyone to improve upon):
# - Onvif authentication
# - Build the SOAP commands at runtime rather than use templates
# - Implement previously mentioned advanced features
#
# Implementing the first two will require additional Perl modules, and adding
# more dependencies to ZoneMinder is always a concern.
#
# On ControlAddress use the format :
# ADDRESS:PORT
# eg : 10.1.2.1:8899
# 10.0.100.1:8899
#
# Use port 8899 for the Netcat camera
#
# Make sure and place a value in the Auto Stop Timeout field.
# Recommend starting with a value of 1 second, and adjust accordingly.
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
my $logindetails = "";
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref( ) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $msg = shift;
my $content_type = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
my $server_endpoint = "http://".$self->{Monitor}->{ControlAddress}."/$cmd";
my $req = HTTP::Request->new( POST => $server_endpoint );
$req->header('content-type' => $content_type);
$req->header('Host' => $self->{Monitor}->{ControlAddress});
$req->header('content-length' => length($msg));
$req->header('accept-encoding' => 'gzip, deflate');
$req->header('connection' => 'Close');
$req->content($msg);
my $res = $self->{ua}->request($req);
if ( $res->is_success ) {
$result = !undef;
} else {
Error( "After sending PTZ command, camera returned the following error:'".$res->status_line()."'" );
}
return( $result );
}
sub getCamParams
{
my $self = shift;
my $msg = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>000</VideoSourceToken></GetImagingSettings></s:Body></s:Envelope>';
my $server_endpoint = "http://".$self->{Monitor}->{ControlAddress}."/onvif/imaging";
my $req = HTTP::Request->new( POST => $server_endpoint );
$req->header('content-type' => 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/GetImagingSettings"');
$req->header('Host' => $self->{Monitor}->{ControlAddress});
$req->header('content-length' => length($msg));
$req->header('accept-encoding' => 'gzip, deflate');
$req->header('connection' => 'Close');
$req->content($msg);
my $res = $self->{ua}->request($req);
if ( $res->is_success ) {
# We should really use an xml or soap library to parse the xml tags
my $content = $res->decoded_content;
if ($content =~ /.*<tt:(Brightness)>(.+)<\/tt:Brightness>.*/) {
$CamParams{$1} = $2;
}
if ($content =~ /.*<tt:(Contrast)>(.+)<\/tt:Contrast>.*/) {
$CamParams{$1} = $2;
}
}
else
{
Error( "Unable to retrieve camera image settings:'".$res->status_line()."'" );
}
}
#autoStop
#This makes use of the ZoneMinder Auto Stop Timeout on the Control Tab
sub autoStop
{
my $self = shift;
my $autostop = shift;
if( $autostop ) {
Debug( "Auto Stop" );
my $cmd = 'onvif/PTZ';
my $msg = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Stop xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><PanTilt>true</PanTilt><Zoom>false</Zoom></Stop></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
usleep( $autostop );
$self->sendCmd( $cmd, $msg, $content_type );
}
}
# Reset the Camera
sub reset
{
Debug( "Camera Reset" );
my $self = shift;
my $cmd = "";
my $msg = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SystemReboot xmlns="http://www.onvif.org/ver10/device/wsdl"/></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver10/device/wsdl/SystemReboot"';
$self->sendCmd( $cmd, $msg, $content_type );
}
#Up Arrow
sub moveConUp
{
Debug( "Move Up" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="0" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Down Arrow
sub moveConDown
{
Debug( "Move Down" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="0" y="-0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Left Arrow
sub moveConLeft
{
Debug( "Move Left" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="-0.49" y="0" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Right Arrow
sub moveConRight
{
Debug( "Move Right" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="0.49" y="0" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Zoom In
sub zoomConTele
{
Debug( "Zoom Tele" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><Zoom x="0.49" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Zoom Out
sub zoomConWide
{
Debug( "Zoom Wide" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><Zoom x="-0.49" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Diagonally Up Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpRight
{
Debug( "Move Diagonally Up Right" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="0.5" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Diagonally Down Right Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownRight
{
Debug( "Move Diagonally Down Right" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="0.5" y="-0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Diagonally Up Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConUpLeft
{
Debug( "Move Diagonally Up Left" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="-0.5" y="0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Diagonally Down Left Arrow
#This camera does not have builtin diagonal commands so we emulate them
sub moveConDownLeft
{
Debug( "Move Diagonally Down Left" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ContinuousMove xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><Velocity><PanTilt x="-0.5" y="-0.5" xmlns="http://www.onvif.org/ver10/schema"/></Velocity></ContinuousMove></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
$self->autoStop( $self->{Monitor}->{AutoStopTimeout} );
}
#Stop
sub moveStop
{
Debug( "Move Stop" );
my $self = shift;
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Stop xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><PanTilt>true</PanTilt><Zoom>false</Zoom></Stop></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/ContinuousMove"';
$self->sendCmd( $cmd, $msg, $content_type );
}
#Set Camera Preset
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Set Preset $preset" );
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SetPreset xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><PresetToken>'.$preset.'</PresetToken></SetPreset></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/SetPreset"';
$self->sendCmd( $cmd, $msg, $content_type );
}
#Recall Camera Preset
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
Debug( "Goto Preset $preset" );
my $cmd = 'onvif/PTZ';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><GotoPreset xmlns="http://www.onvif.org/ver20/ptz/wsdl"><ProfileToken>000</ProfileToken><PresetToken>'.$preset.'</PresetToken></GotoPreset></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/ptz/wsdl/GotoPreset"';
$self->sendCmd( $cmd, $msg, $content_type );
}
#Horizontal Patrol
#To be determined if this camera supports this feature
sub horizontalPatrol
{
Debug( "Horizontal Patrol" );
my $self = shift;
my $cmd = '';
my $msg ='';
my $content_type = '';
# $self->sendCmd( $cmd, $msg, $content_type );
Error( "PTZ Command not implemented in control script." );
}
#Horizontal Patrol Stop
#To be determined if this camera supports this feature
sub horizontalPatrolStop
{
Debug( "Horizontal Patrol Stop" );
my $self = shift;
my $cmd = '';
my $msg ='';
my $content_type = '';
# $self->sendCmd( $cmd, $msg, $content_type );
Error( "PTZ Command not implemented in control script." );
}
# Increase Brightness
sub irisAbsOpen
{
Debug( "Iris $CamParams{'Brightness'}" );
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'Brightness'});
my $step = $self->getParam( $params, 'step' );
my $max = 100;
$CamParams{'Brightness'} += $step;
$CamParams{'Brightness'} = $max if ($CamParams{'Brightness'} > $max);
my $cmd = 'onvif/imaging';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>000</VideoSourceToken><ImagingSettings><Brightness xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Brightness'}.'</Brightness></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
$self->sendCmd( $cmd, $msg, $content_type );
}
# Decrease Brightness
sub irisAbsClose
{
Debug( "Iris $CamParams{'Brightness'}" );
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'brightness'});
my $step = $self->getParam( $params, 'step' );
my $min = 0;
$CamParams{'Brightness'} -= $step;
$CamParams{'Brightness'} = $min if ($CamParams{'Brightness'} < $min);
my $cmd = 'onvif/imaging';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>000</VideoSourceToken><ImagingSettings><Brightness xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Brightness'}.'</Brightness></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
$self->sendCmd( $cmd, $msg, $content_type );
}
# Increase Contrast
sub whiteAbsIn
{
Debug( "Iris $CamParams{'Contrast'}" );
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'Contrast'});
my $step = $self->getParam( $params, 'step' );
my $max = 100;
$CamParams{'Contrast'} += $step;
$CamParams{'Contrast'} = $max if ($CamParams{'Contrast'} > $max);
my $cmd = 'onvif/imaging';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>000</VideoSourceToken><ImagingSettings><Contrast xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Contrast'}.'</Contrast></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
}
# Decrease Contrast
sub whiteAbsOut
{
Debug( "Iris $CamParams{'Contrast'}" );
my $self = shift;
my $params = shift;
$self->getCamParams() unless($CamParams{'Contrast'});
my $step = $self->getParam( $params, 'step' );
my $min = 0;
$CamParams{'Contrast'} -= $step;
$CamParams{'Contrast'} = $min if ($CamParams{'Contrast'} < $min);
my $cmd = 'onvif/imaging';
my $msg ='<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><SetImagingSettings xmlns="http://www.onvif.org/ver20/imaging/wsdl"><VideoSourceToken>000</VideoSourceToken><ImagingSettings><Contrast xmlns="http://www.onvif.org/ver10/schema">'.$CamParams{'Contrast'}.'</Contrast></ImagingSettings><ForcePersistence>true</ForcePersistence></SetImagingSettings></s:Body></s:Envelope>';
my $content_type = 'application/soap+xml; charset=utf-8; action="http://www.onvif.org/ver20/imaging/wsdl/SetImagingSettings"';
}
1;

View File

@ -133,8 +133,10 @@ sub sendCmd
my $result = undef; my $result = undef;
# Pelco P protocol checksum is created by XOR'ing the first seven bytes in the message
# including the first byte, the STX sync packet
my $checksum = 0x00; my $checksum = 0x00;
for ( my $i = 1; $i < int(@$cmd); $i++ ) for ( my $i = 0; $i < int(@$cmd); $i++ )
{ {
$checksum ^= $cmd->[$i]; $checksum ^= $cmd->[$i];
} }

View File

@ -0,0 +1,227 @@
# ==========================================================================
#
# ZoneMinder Vivotek ePTZ Control Protocol Module
# Copyright (C) 2015 Robin Daermann
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the Vivotek ePTZ camera control
# protocol
#
package ZoneMinder::Control::Vivotek_ePTZ;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
# ==========================================================================
#
# Vivotek ePTZ Control Protocol
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
Debug( "Camera New" );
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
Debug( "Camera AUTOLOAD" );
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
Debug( "Camera open" );
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub printMsg
{
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my ($self, $cmd, $speedcmd) = @_;
my $result = undef;
printMsg( $speedcmd, "Tx" );
printMsg( $cmd, "Tx" );
my $req = HTTP::Request->new( GET => "http://" . $self->{Monitor}->{ControlAddress} . "/cgi-bin/camctrl/eCamCtrl.cgi?stream=0&$speedcmd&$cmd" );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Request failed: '" . $res->status_line() . "' (URI: '" . $req->as_string() . "')" );
}
return( $result );
}
sub moveConUp
{
my ($self, $params) = @_;
my $speed = 'speedtilt=' . ($params->{tiltspeed} - 6);
Debug( "Move Up" );
$self->sendCmd( 'move=up', $speed );
}
sub moveConDown
{
my ($self, $params) = @_;
my $speed = 'speedtilt=' . ($params->{tiltspeed} - 6);
Debug( "Move Down" );
$self->sendCmd( 'move=down', $speed );
}
sub moveConLeft
{
my ($self, $params) = @_;
my $speed = 'speedpan=-' . $params->{panspeed};
Debug( "Move Left" );
$self->sendCmd( 'move=left', $speed );
}
sub moveConRight
{
my ($self, $params) = @_;
my $speed = 'speedpan=' . ($params->{panspeed} - 6);
Debug( "Move Right" );
$self->sendCmd( 'move=right', $speed );
}
sub moveStop
{
my $self = shift;
Debug( "Move Stop" );
# not implemented
}
sub zoomConTele
{
my ($self, $params) = @_;
my $speed = 'speedzoom=' . ($params->{speed} - 6);
Debug( "Zoom In" );
$self->sendCmd( 'zoom=tele', $speed );
}
sub zoomConWide
{
my ($self, $params) = @_;
my $speed = 'speedzoom=' . ($params->{speed} - 6);
Debug( "Zoom Out" );
$self->sendCmd( 'zoom=wide', $speed );
}
sub reset
{
my $self = shift;
Debug( "Camera Reset" );
$self->sendCmd( 'move=home' );
}
1;
__END__
=head1 NAME
ZoneMinder::Control::Vivotek_ePTZ - ZoneMinder Perl extension for Vivotek ePTZ
camera control protocol
=head1 SYNOPSIS
use ZoneMinder::Control::Vivotek_ePTZ;
=head1 DESCRIPTION
This module implements the ePTZ protocol used in various Vivotek IP cameras,
developed with a Vivotek IB8369 model.
Currently, only simple pan, tilt and zoom function is implemented. Presets will
follow later.
=head2 EXPORT
None.
=head1 SEE ALSO
I would say, see ZoneMinder::Control documentation. But it is a stub.
=head1 AUTHOR
Robin Daermann E<lt>r.daermann@ids-services.deE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2015 by Robin Daermann
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -0,0 +1,399 @@
# ==========================================================================
#
# ZoneMinder Wanscam HW0025 IP Control Protocol Module, $Date: 2009-11-25 09:20:00 +0000 (Wed, 04 Nov 2009) $, $Revision: 0001 $
# Copyright (C) 2001-2015 Florian Neumair
# Modified for use with Foscam FI8918W IP Camera by Dave Harris
# Modified Feb 2011 by Howard Durdle (http://durdl.es/x) to:
# fix horizontal panning, add presets and IR on/off
# use Control Device field to pass username and password
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
#
# This module contains the implementation of the Wanscam HW0025 IP camera control
# protocol
#
# Known working Devices:
# * Wanscam HW0025
# * IPCC-7210W
#
package ZoneMinder::Control::WanscamHW0025;
use 5.006;
use strict;
use warnings;
require ZoneMinder::Base;
require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control);
# ==========================================================================
#
# Wanscam HW0025 IP Control Protocol
#
# ==========================================================================
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub new
{
my $class = shift;
my $id = shift;
my $self = ZoneMinder::Control->new( $id );
bless( $self, $class );
srand( time() );
return $self;
}
our $AUTOLOAD;
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift;
$self->loadMonitor();
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
$self->{state} = 'open';
}
sub close
{
my $self = shift;
$self->{state} = 'closed';
}
sub printMsg
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift;
my $cmd = shift;
my $result = undef;
printMsg( $cmd, "Tx" );
#print( "http://$address/$cmd\n" );
my $req = HTTP::Request->new( GET=>"http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} );
Info( "http://".$self->{Monitor}->{ControlAddress}."/$cmd".$self->{Monitor}->{ControlDevice} );
my $res = $self->{ua}->request($req);
if ( $res->is_success )
{
$result = !undef;
}
else
{
Error( "Error check failed: '".$res->status_line()."'" );
}
return( $result );
}
sub cameraReset
{
my $self = shift;
Debug( "Camera Reset" );
my $cmd = "reboot.cgi?";
$self->sendCmd( $cmd );
}
#Up Arrow
sub moveConUp
{
my $self = shift;
my $params = shift;
Debug( "Move Up" );
my $cmd = "decoder_control.cgi?command=0&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Down Arrow
sub moveConDown
{
my $self = shift;
my $params = shift;
Debug( "Move Down" );
my $cmd = "decoder_control.cgi?command=2&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Left Arrow
sub moveConLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Left" );
my $cmd = "decoder_control.cgi?command=4&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Right Arrow
sub moveConRight
{
my $self = shift;
my $params = shift;
Debug( "Move Right" );
my $cmd = "decoder_control.cgi?command=6&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Up Right Arrow
sub moveConUpRight
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Up Right" );
my $cmd = "decoder_control.cgi?command=91&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Down Right Arrow
sub moveConDownRight
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Down Right" );
my $cmd = "decoder_control.cgi?command=93&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Up Left Arrow
sub moveConUpLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Up Left" );
my $cmd = "decoder_control.cgi?command=90&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Diagonally Down Left Arrow
sub moveConDownLeft
{
my $self = shift;
my $params = shift;
Debug( "Move Diagonally Down Left" );
my $cmd = "decoder_control.cgi?command=92&onestep=1&";
$self->sendCmd( $cmd );
my $autostop = $self->getParam( $params, 'autostop', 0 );
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
{
usleep( $self->{Monitor}->{AutoStopTimeout} );
$self->moveStop( $params );
}
}
#Stop
sub moveStop
{
my $self = shift;
Debug( "Move Stop" );
my $cmd = "decoder_control.cgi?command=1&onestep=1&";
$self->sendCmd( $cmd );
}
#Move Camera to Home Position
sub presetHome
{
my $self = shift;
Debug( "Home Preset" );
my $cmd = "decoder_control.cgi?command=25&onestep=0&";
$self->sendCmd( $cmd );
}
# zoom out
sub zoomRelTele
{
my $self = shift;
Debug( "Zoom Tele" );
my $cmd = "camera_control.cgi?param=17&value=1&";
$self->sendCmd( $cmd );
}
#zoom in
sub zoomRelWide
{
my $self = shift;
Debug( "Zoom Wide" );
my $cmd = "camera_control.cgi?param=18&value=1&";
$self->sendCmd( $cmd );
}
#Set preset
sub presetSet
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
my $presetCmd = 30 + (($preset-1)*2);
Debug( "Set Preset $preset with cmd $presetCmd" );
my $cmd = "decoder_control.cgi?command=$presetCmd&onestep=0&sit=$presetCmd&";
$self->sendCmd( $cmd );
}
#Goto preset
sub presetGoto
{
my $self = shift;
my $params = shift;
my $preset = $self->getParam( $params, 'preset' );
my $presetCmd = 31 + (($preset-1)*2);
Debug( "Goto Preset $preset with cmd $presetCmd" );
my $cmd = "decoder_control.cgi?command=$presetCmd&onestep=0&sit=$presetCmd&";
$self->sendCmd( $cmd );
}
#Turn IR on
sub wake
{
my $self = shift;
Debug( "Wake - IR on" );
my $cmd = "camera_control.cgi?param=14&value=1&";
$self->sendCmd( $cmd );
}
#Turn IR off
sub sleep
{
my $self = shift;
Debug( "Sleep - IR off" );
my $cmd = "camera_control.cgi?param=14&value=0&";
$self->sendCmd( $cmd );
}
1;
__END__
# Below is stub documentation for your module. You'd better edit it!
=head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah
=head1 SYNOPSIS
use ZoneMinder::Control::Wanscam
blah blah blah
=head1 DESCRIPTION
Stub documentation for ZoneMinder, created by h2xs. It looks like the
author of the extension was negligent enough to leave the stub
unedited.
Blah blah blah.
=head2 EXPORT
None by default.
=head1 SEE ALSO
Mention other useful documentation such as the documentation of
related modules or operating system documentation (such as man pages
in UNIX), or any relevant external documentation such as RFCs or
standards.
If you have a mailing list set up for your module, mention it here.
If you have a web site set up for your module, mention it here.
=head1 AUTHOR
Philip Coombes, <philip.coombes@zoneminder.com>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2001-2008 Philip Coombes
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.3 or,
at your option, any later version of Perl 5 you may have available.
=cut

View File

@ -62,7 +62,10 @@ sub open
local *sfh; local *sfh;
#sysopen( *sfh, $conn->{path}, O_NONBLOCK|O_RDONLY ) or croak( "Can't sysopen: $!" ); #sysopen( *sfh, $conn->{path}, O_NONBLOCK|O_RDONLY ) or croak( "Can't sysopen: $!" );
#open( *sfh, "<".$conn->{path} ) or croak( "Can't open: $!" ); #open( *sfh, "<".$conn->{path} ) or croak( "Can't open: $!" );
open( *sfh, "+<", $self->{path} ) or croak( "Can't open: $!" ); if ( ! open( *sfh, "+<", $self->{path} ) ) {
Error( "Can't open file at $$self{path}: $!" );
croak( "Can't open file at $$self{path}: $!" );
}
$self->{state} = 'open'; $self->{state} = 'open';
$self->{handle} = *sfh; $self->{handle} = *sfh;
} }
@ -73,7 +76,7 @@ __END__
=head1 NAME =head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah ZoneMinder::Trigger::Channel::File - ZOneMinder object for a file based trigger channel
=head1 SYNOPSIS =head1 SYNOPSIS

View File

@ -61,12 +61,21 @@ sub open
{ {
my $self = shift; my $self = shift;
local *sfh; local *sfh;
my $saddr = sockaddr_in( $self->{port}, INADDR_ANY ); if ( ! socket( *sfh, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) ) {
socket( *sfh, PF_INET, SOCK_STREAM, getprotobyname('tcp') ) Error( "Can't open socket: $!" );
or croak( "Can't open socket: $!" ); croak( "Can't open socket: $!" );
}
setsockopt( *sfh, SOL_SOCKET, SO_REUSEADDR, 1 ); setsockopt( *sfh, SOL_SOCKET, SO_REUSEADDR, 1 );
bind( *sfh, $saddr ) or croak( "Can't bind: $!" );
listen( *sfh, SOMAXCONN ) or croak( "Can't listen: $!" ); my $saddr = sockaddr_in( $self->{port}, INADDR_ANY );
if ( ! bind( *sfh, $saddr ) ) {
Error( "Can't bind to port $$self{port}: $!" );
croak( "Can't bind to port $$self{port}: $!" );
}
if ( ! listen( *sfh, SOMAXCONN ) ) {
Error( "Can't listen: $!" );
croak( "Can't listen: $!" );
}
$self->{state} = 'open'; $self->{state} = 'open';
$self->{handle} = *sfh; $self->{handle} = *sfh;
} }
@ -95,7 +104,7 @@ __END__
=head1 NAME =head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah ZoneMinder::Trigger::Channel::Inet
=head1 SYNOPSIS =head1 SYNOPSIS

View File

@ -63,9 +63,18 @@ sub open
local *sfh; local *sfh;
unlink( $self->{path} ); unlink( $self->{path} );
my $saddr = sockaddr_un( $self->{path} ); my $saddr = sockaddr_un( $self->{path} );
socket( *sfh, PF_UNIX, SOCK_STREAM, 0 ) or croak( "Can't open socket: $!" ); if ( ! socket( *sfh, PF_UNIX, SOCK_STREAM, 0 ) ) {
bind( *sfh, $saddr ) or croak( "Can't bind: $!" ); Error( "Can't open unix socket at $$self{path}: $!" );
listen( *sfh, SOMAXCONN ) or croak( "Can't listen: $!" ); croak( "Can't open unix socket at $$self{path}: $!" );
}
if ( ! bind( *sfh, $saddr ) ) {
Error( "Can't bind unix socket at $$self{path}: $!" );
croak( "Can't bind unix socket at $$self{path}: $!" );
}
if ( ! listen( *sfh, SOMAXCONN ) ) {
Error( "Can't listen: $!" );
croak( "Can't listen: $!" );
}
$self->{handle} = *sfh; $self->{handle} = *sfh;
} }
@ -93,12 +102,11 @@ __END__
=head1 NAME =head1 NAME
ZoneMinder::Database - Perl extension for blah blah blah ZoneMinder::Trigger::Channel::Unix - Object for Unix socket channel
=head1 SYNOPSIS =head1 SYNOPSIS
use ZoneMinder::Database; See zmtrigger.pl
blah blah blah
=head1 DESCRIPTION =head1 DESCRIPTION

View File

@ -419,9 +419,9 @@ sub toPreset
foreach (@data) { foreach (@data) {
s/\b(?:\d{1,3}\.){3}\d{1,3}\b/<ip-address>/; # ip address s/\b(?:\d{1,3}\.){3}\d{1,3}\b/<ip-address>/; # ip address
s/<ip-address>:(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$/<ip-address>:<port>/; # tcpip port s/<ip-address>:(6553[0-5]|655[0-2]\d|65[0-4]\d\d|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}|0)$/<ip-address>:<port>/; # tcpip port
s/\/\/.*:.*@/\/\/<username>:<pwd>@/; # user & pwd preceeding an ip address s/\/\/.*:.*@/\/\/<username>:<pwd>@/; # user & pwd preceding an ip address
s/(&|\?)(user|username)=\w\w*(&|\?)/$1$2=<username>$3/i; # username embeded in url s/(&|\?)(user|username)=\w\w*(&|\?)/$1$2=<username>$3/i; # username embedded in url
s/(&|\?)(pwd|password)=\w\w*(&|\?)/$1$2=<pwd>$3/i; # password embeded in url s/(&|\?)(pwd|password)=\w\w*(&|\?)/$1$2=<pwd>$3/i; # password embedded in url
s/\w\w*:\w\w*/<username>:<pwd>/; # user & pwd in their own field s/\w\w*:\w\w*/<username>:<pwd>/; # user & pwd in their own field
s/\/dev\/video\d\d*/\/dev\/video<?>/; # local video devices s/\/dev\/video\d\d*/\/dev\/video<?>/; # local video devices
} }

View File

@ -87,7 +87,8 @@ my @daemons = (
'zmx10.pl', 'zmx10.pl',
'zmwatch.pl', 'zmwatch.pl',
'zmupdate.pl', 'zmupdate.pl',
'zmtrack.pl' 'zmtrack.pl',
'zmtelemetry.pl',
); );
my $command = shift @ARGV; my $command = shift @ARGV;
@ -250,13 +251,15 @@ sub run
{ {
print( $PID $$ ); print( $PID $$ );
close( $PID ); close( $PID );
} else {
Error( "Can't open pid file at " . ZM_PID );
} }
killAll( 1 ); killAll( 1 );
socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" ); socket( SERVER, PF_UNIX, SOCK_STREAM, 0 ) or Fatal( "Can't open socket: $!" );
unlink( main::SOCK_FILE ); unlink( main::SOCK_FILE ) or Error( "Unable to unlink " . main::SOCK_FILE );
bind( SERVER, $saddr ) or Fatal( "Can't bind: $!" ); bind( SERVER, $saddr ) or Fatal( "Can't bind to " . main::SOCK_FILE . ": $!" );
listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" ); listen( SERVER, SOMAXCONN ) or Fatal( "Can't listen: $!" );
$SIG{CHLD} = \&reaper; $SIG{CHLD} = \&reaper;

View File

@ -935,7 +935,8 @@ sub uploadArchFile
if $Config{ZM_UPLOAD_PORT}; if $Config{ZM_UPLOAD_PORT};
$sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT} $sftpOptions{timeout} = $Config{ZM_UPLOAD_TIMEOUT}
if $Config{ZM_UPLOAD_TIMEOUT}; if $Config{ZM_UPLOAD_TIMEOUT};
$sftpOptions{more} = [ '-o'=>'StrictHostKeyChecking=no' ]; $sftpOptions{more} = [ '-o'=>'StrictHostKeyChecking=no' ]
if ! $Config{ZM_UPLOAD_STRICT};
$Net::SFTP::Foreign::debug = -1 $Net::SFTP::Foreign::debug = -1
if $Config{ZM_UPLOAD_DEBUG}; if $Config{ZM_UPLOAD_DEBUG};
my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions ); my $sftp = Net::SFTP::Foreign->new( $Config{ZM_UPLOAD_HOST}, %sftpOptions );

View File

@ -285,6 +285,10 @@ if ( $command =~ /^(?:start|restart)$/ )
{ {
runCommand( "zmdc.pl start zmupdate.pl -c" ); runCommand( "zmdc.pl start zmupdate.pl -c" );
} }
if ( $Config{ZM_TELEMETRY_DATA} )
{
runCommand( "zmdc.pl start zmtelemetry.pl" );
}
} }
else else
{ {

343
scripts/zmtelemetry.pl.in Normal file
View File

@ -0,0 +1,343 @@
#!/usr/bin/perl -w
#
# ==========================================================================
#
# ZoneMinder Update Script, $Date$, $Revision$
# Copyright (C) 2001-2008 Philip Coombes
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
=head1 NAME
zmtelemetry.pl - Send usage information to the ZoneMinder development team
=head1 SYNOPSIS
zmtelemetry.pl
=head1 DESCRIPTION
This script collects usage information of the local system and sends it to the
ZoneMinder development team. This data will be used to determine things like
who and where our customers are, how big their systems are, the underlying
hardware and operating system, etc. This is being done for the sole purpoase of
creating a better product for our target audience. This script is intended to
be completely transparent to the end user, and can be disabled from the web
console under Options.
=head1 OPTIONS
none currently
=cut
use strict;
use bytes;
@EXTRA_PERL_LIB@
use ZoneMinder;
use DBI;
use Getopt::Long;
use autouse 'Pod::Usage'=>qw(pod2usage);
use LWP::UserAgent;
use Sys::MemInfo qw(totalmem);
use Sys::CPU qw(cpu_count);
use POSIX qw(strftime uname);
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
use constant CHECK_INTERVAL => (14*24*60*60); # Interval between version checks
# Setting these as contants for now.
# Alternatively, we can put these in the dB and then retrieve using the Config hash.
use constant ZM_TELEMETRY_SERVER_ENDPOINT => 'https://zmanon:2b2d0b4skps@telemetry.zoneminder.com/zmtelemetry/testing5';
if ( $Config{ZM_TELEMETRY_DATA} )
{
print( "Update agent starting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
my $lastCheck = $Config{ZM_TELEMETRY_LAST_CHECK};
while( 1 ) {
my $now = time();
if ( ($now-$lastCheck) > CHECK_INTERVAL ) {
Info( "Colleting data to send to ZoneMinder Telemetry server." );
my $dbh = zmDbConnect();
# Build the telemetry hash
# We should keep *BSD systems in mind when calling system commands
my %telemetry;
$telemetry{uuid} = getUUID($dbh);
$telemetry{ip} = getIP();
$telemetry{timestamp} = strftime( "%Y-%m-%dT%H:%M:%S%z", localtime() );
$telemetry{monitor_count} = countQuery($dbh,"Monitors");
$telemetry{event_count} = countQuery($dbh,"Events");
$telemetry{architecture} = runSysCmd("uname -p");
($telemetry{kernel}, $telemetry{distro}, $telemetry{version}) = getDistro();
$telemetry{zm_version} = ZoneMinder::Base::ZM_VERSION;
$telemetry{system_memory} = totalmem();
$telemetry{processor_count} = cpu_count();
$telemetry{monitors} = getMonitorRef($dbh);
Info( "Sending data to ZoneMinder Telemetry server." );
my $result = jsonEncode( \%telemetry );
if ( sendData($result) ) {
$lastCheck = $now;
my $sql = "update Config set Value = ? where Name = 'ZM_TELEMETRY_LAST_UPLOAD'";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute( "$lastCheck" ) or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
}
}
sleep( 3600 );
}
print( "Update agent exiting at ".strftime( '%y/%m/%d %H:%M:%S', localtime() )."\n" );
}
###############
# SUBROUTINES #
###############
# Find, verify, then run the supplied system command
sub runSysCmd {
my $msg = shift;
my @arguments = split(/ /,$msg);
chomp($arguments[0]);
my $path = qx( which $arguments[0] );
my $status = $? >> 8;
my $result = "";
if ( !$path || $status ) {
Warning( "Cannot find the $arguments[0] executable." );
} else {
chomp($path);
$arguments[0] = $path;
my $cmd = join(" ",@arguments);
$result = qx( $cmd );
chomp($result);
}
return $result;
}
# Upload message data to ZoneMinder telemetry server
sub sendData {
my $msg = shift;
my $ua = LWP::UserAgent->new;
my $server_endpoint = ZM_TELEMETRY_SERVER_ENDPOINT;
if ( $Config{ZM_UPDATE_CHECK_PROXY} ) {
$ua->proxy( "https", $Config{ZM_UPDATE_CHECK_PROXY} );
}
Debug("Posting telemetry data to: $server_endpoint");
# set custom HTTP request header fields
my $req = HTTP::Request->new(POST => $server_endpoint);
$req->header('content-type' => 'application/x-www-form-urlencoded');
$req->header('content-length' => length($msg));
$req->header('connection' => 'Close');
$req->content($msg);
my $resp = $ua->request($req);
my $resp_msg = $resp->decoded_content;
my $resp_code = $resp->code;
if ($resp->is_success) {
Info("Telemetry data uploaded successfully.");
Debug("Telemetry server upload success response message: $resp_msg");
} else {
Warning("Telemetry server returned HTTP POST error code: $resp_code");
Debug("Telemetry server upload failure response message: $resp_msg");
}
return $resp->is_success;
}
# Retrieves the UUID from the database. Creates a new UUID if one does not exist.
sub getUUID {
my $dbh = shift;
my $uuid= "";
# Verify the current UUID is valid and not nil
if (( $Config{ZM_TELEMETRY_UUID} =~ /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i ) && ( $Config{ZM_TELEMETRY_UUID} ne "00000000-0000-0000-0000-000000000000" )) {
$uuid = $Config{ZM_TELEMETRY_UUID};
} else {
my $sql = "SELECT uuid()";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
$uuid = $Config{ZM_TELEMETRY_UUID} = $sth->fetchrow_array();
$sth->finish();
$sql = "UPDATE Config set Value = ? WHERE Name = 'ZM_TELEMETRY_UUID'";
$sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
$res = $sth->execute( "$uuid" ) or die( "Can't execute: ".$sth->errstr() );
$sth->finish();
}
Debug("Using UUID of: $uuid");
return $uuid;
}
# Retrieves the local server's external IP address
sub getIP {
my $ipaddr = "0.0.0.0";
my $ua = LWP::UserAgent->new;
my $server_endpoint = "https://wiki.zoneminder.com/ip.php";
my $req = HTTP::Request->new(GET => $server_endpoint);
my $resp = $ua->request($req);
if ($resp->is_success) {
$ipaddr = $resp->decoded_content;
}
Debug("Found external ip address of: $ipaddr");
return $ipaddr;
}
# As the name implies, just your average mysql count query
sub countQuery {
my $dbh = shift;
my $table = shift;
my $sql = "SELECT count(*) FROM $table";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
my $count = $sth->fetchrow_array();
$sth->finish();
return $count
}
# Returns a reference to an array of hashes containing data from all monitors
sub getMonitorRef {
my $dbh = shift;
my $sql = "SELECT Id,Name,Type,Function,Width,Height,Colours,MaxFPS,AlarmMaxFPS FROM Monitors";
my $sth = $dbh->prepare_cached( $sql ) or die( "Can't prepare '$sql': ".$dbh->errstr() );
my $res = $sth->execute() or die( "Can't execute: ".$sth->errstr() );
my $arrayref = $sth->fetchall_arrayref({});
return $arrayref;
}
sub getDistro {
my $kernel = "";
my $distro = "";
my $version = "";
my @uname = uname();
if ( $uname[0] =~ /Linux/ ) {
Debug("Linux distro detected.");
($kernel, $distro, $version) = linuxDistro();
} elsif ( $uname[0] =~ /.*BSD/ ) {
Debug("BSD distro detected.");
$kernel = $uname[3];
$distro = $uname[0];
$version = $uname[2];
} elsif ( $uname[0] =~ /Darwin/ ) {
Debug("Mac OS distro detected.");
$kernel = $uname[3];
$distro = runSysCmd("sw_vers -productName");
$version = runSysCmd("sw_vers -productVersion");
} elsif ( $uname[0] =~ /SunOS|Solaris/ ) {
Debug("Sun Solaris detected.");
$kernel = $uname[3];
$distro = $uname[1];
$version = $uname[2];
} else {
Warning("ZoneMinder was unable to determine the host system. Please report.");
$kernel = "Unknown";
$distro = "Unknown";
$version = "Unknown";
}
return ($kernel, $distro, $version);
}
sub linuxDistro {
my @uname = uname();
my $kernel = $uname[2];
my $distro = "Unknown Linux Distro";
my $version = "Unknown Linux Version";
my $found = 0;
# os-release is the standard for many new distros based on systemd
if ( -f "/etc/os-release" ) {
open(my $RELFILE,"<","/etc/os-release") or die( "Can't Open file: $!\n" );
while (<$RELFILE>) {
if ( /^NAME=(")?(.*)(?(1)\1|).*$/ ) {
$distro = $2;
$found = 1;
}
if ( /^VERSION_ID=(")?(.*)(?(1)\1|).*$/ ) {
$version = $2;
$found = 1;
}
}
close $RELFILE;
# exists on many distros but does not always contain useful information, such as redhat
} elsif ( -f "/etc/lsb-release" ) {
open(my $RELFILE,"<","/etc/lsb-release") or die( "Can't Open file: $!\n" );
while (<$RELFILE>) {
if ( /^DISTRIB_DESCRIPTION=(")?(.*)(?(1)\1|).*$/ ) {
$distro = $2;
$found = 1;
}
if ( /^DISTRIB_RELEASE=(")?(.*)(?(1)\1|).*$/ ) {
$version = $2;
$found = 1;
}
}
close $RELFILE;
}
# If all else fails, search through a list of known release files until we find one
if ( !$found ) {
my @releasefile = ("/etc/SuSE-release", "/etc/redhat-release", "/etc/redhat_version",
"/etc/fedora-release", "/etc/slackware-release", "/etc/slackware-version",
"/etc/debian_release", "/etc/debian_version", "/etc/mandrake-release",
"/etc/yellowdog-release", "/etc/gentoo-release");
foreach (@releasefile) {
if ( -f $_ ) {
open(my $RELFILE,"<",$_) or die( "Can't Open file: $!\n" );
while (<$RELFILE>) {
if ( /(.*).* (\d+\.?\d*) .*/ ) {
$distro = $1;
$version = $2;
$found = 1;
}
}
close $RELFILE;
last;
}
}
}
if ( !$found ) {
Warning("ZoneMinder was unable to determine Linux distro. Please report.");
}
return ($kernel, $distro, $version);
}

View File

@ -135,14 +135,14 @@ use ZoneMinder::Trigger::Connection;
my @connections; my @connections;
push( @connections, push( @connections,
ZoneMinder::Trigger::Connection->new( ZoneMinder::Trigger::Connection->new(
name=>"Chan1", name=>"Chan1 TCP on port 6802",
channel=>ZoneMinder::Trigger::Channel::Inet->new( port=>6802 ), channel=>ZoneMinder::Trigger::Channel::Inet->new( port=>6802 ),
mode=>"rw" mode=>"rw"
) )
); );
push( @connections, push( @connections,
ZoneMinder::Trigger::Connection->new( ZoneMinder::Trigger::Connection->new(
name=>"Chan2", name=>"Chan2 Unix Socket at " . $Config{ZM_PATH_SOCKS}.'/zmtrigger.sock',
channel=>ZoneMinder::Trigger::Channel::Unix->new( channel=>ZoneMinder::Trigger::Channel::Unix->new(
path=>$Config{ZM_PATH_SOCKS}.'/zmtrigger.sock' path=>$Config{ZM_PATH_SOCKS}.'/zmtrigger.sock'
), ),

View File

@ -23,7 +23,7 @@
=head1 NAME =head1 NAME
zmupdate.pl - check and upgrade Zoneminer database zmupdate.pl - check and upgrade ZoneMinder database
=head1 SYNOPSIS =head1 SYNOPSIS

View File

@ -2,6 +2,7 @@
/* */ /* */
/* Font file generated by schrorg */ /* Font file generated by schrorg */
/* based on the font file generated by rthelen */ /* based on the font file generated by rthelen */
/* using utils/mk_bigfont.pl */
/* */ /* */
/***********************************************************/ /***********************************************************/

View File

@ -136,9 +136,9 @@ void zmLoadConfig()
} }
if ( ! staticConfig.SERVER_ID ) { if ( ! staticConfig.SERVER_ID ) {
Info( "No Server ID or Name specified in config. Not using Multi-Server Mode." ); Debug( 1, "No Server ID or Name specified in config. Not using Multi-Server Mode." );
} else { } else {
Info( "Server is %d: using Multi-Server Mode.", staticConfig.SERVER_ID ); Debug( 1, "Server is %d: using Multi-Server Mode.", staticConfig.SERVER_ID );
} }
} }

View File

@ -1244,7 +1244,7 @@ void EventStream::processCommand( const CmdMsg *msg )
DataMsg status_msg; DataMsg status_msg;
status_msg.msg_type = MSG_DATA_EVENT; status_msg.msg_type = MSG_DATA_EVENT;
memcpy( &status_msg.msg_data, &status_data, sizeof(status_msg.msg_data) ); memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) );
if ( sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) ) < 0 ) if ( sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) ) < 0 )
{ {
//if ( errno != EAGAIN ) //if ( errno != EAGAIN )

View File

@ -4073,7 +4073,7 @@ void MonitorStream::processCommand( const CmdMsg *msg )
DataMsg status_msg; DataMsg status_msg;
status_msg.msg_type = MSG_DATA_WATCH; status_msg.msg_type = MSG_DATA_WATCH;
memcpy( &status_msg.msg_data, &status_data, sizeof(status_msg.msg_data) ); memcpy( &status_msg.msg_data, &status_data, sizeof(status_data) );
int nbytes = 0; int nbytes = 0;
if ( (nbytes = sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) )) < 0 ) if ( (nbytes = sendto( sd, &status_msg, sizeof(status_msg), MSG_DONTWAIT, (sockaddr *)&rem_addr, sizeof(rem_addr) )) < 0 )
{ {

View File

@ -199,7 +199,7 @@ int RemoteCameraHttp::ReadData( Buffer &buffer, int bytes_expected )
return( -1 ); return( -1 );
} }
// There can be lots of bytes available. I've seen 4MB or more. This will vastly inflate our buffer size unneccessarily. // There can be lots of bytes available. I've seen 4MB or more. This will vastly inflate our buffer size unnecessarily.
if ( total_bytes_to_read > ZM_NETWORK_BUFSIZ ) { if ( total_bytes_to_read > ZM_NETWORK_BUFSIZ ) {
total_bytes_to_read = ZM_NETWORK_BUFSIZ; total_bytes_to_read = ZM_NETWORK_BUFSIZ;
Debug(3, "Just getting 32K" ); Debug(3, "Just getting 32K" );

View File

@ -274,7 +274,7 @@ int main( int argc, char *argv[] )
Debug( 1, "Read frame header, expecting %ld bytes of image", frame_header.image_length ); Debug( 1, "Read frame header, expecting %ld bytes of image", frame_header.image_length );
static unsigned char image_data[ZM_MAX_IMAGE_SIZE]; static unsigned char image_data[ZM_MAX_IMAGE_SIZE];
// Read for pipe and loop until bytes expected have been read or an error occures // Read for pipe and loop until bytes expected have been read or an error occurs
int bytes_read = 0; int bytes_read = 0;
do do
{ {

View File

@ -52,12 +52,22 @@ else
ln -sf distros/ubuntu1504_cmake debian ln -sf distros/ubuntu1504_cmake debian
fi; fi;
# Auto-install all ZoneMinder's depedencies using the Debian control file
sudo apt-get install devscripts equivs
sudo mk-build-deps -ir ./debian/control
if [ -z `hostname -d` ] ; then
AUTHOR="`getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1` <`whoami`@`hostname`.local>"
else
AUTHOR="`getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1` <`whoami`@`hostname`>"
fi
cat <<EOF > debian/changelog cat <<EOF > debian/changelog
zoneminder ($VERSION-$DISTRO-$SNAPSHOT) $DISTRO; urgency=medium zoneminder ($VERSION-$DISTRO-$SNAPSHOT) $DISTRO; urgency=medium
* *
-- Isaac Connor <iconnor@connortechnology.com> $DATE -- $AUTHOR $DATE
EOF EOF
#rm -rf .git #rm -rf .git

View File

@ -6,8 +6,7 @@
<Directory "/usr/lib/cgi-bin"> <Directory "/usr/lib/cgi-bin">
AllowOverride None AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny require all granted
Allow from all
</Directory> </Directory>
</VirtualHost> </VirtualHost>

5
utils/docker/phpdate.ini Normal file
View File

@ -0,0 +1,5 @@
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone = GMT

View File

@ -1,5 +1,11 @@
#!/bin/bash #!/bin/bash
# Prepare proper amount of shared memory
# For H.264 cameras it may be necessary to increase the amout of shared memory
# to 2048 megabytes.
umount /dev/shm
mount -t tmpfs -o rw,nosuid,nodev,noexec,relatime,size=512M tmpfs /dev/shm
# Start MySQL # Start MySQL
/usr/bin/mysqld_safe & /usr/bin/mysqld_safe &
@ -25,7 +31,13 @@ done
mysql -u root < db/zm_create.sql mysql -u root < db/zm_create.sql
# Add the ZoneMinder DB user # Add the ZoneMinder DB user
mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zm'@'localhost' identified by 'zm'" mysql -u root -e "grant insert,select,update,delete,lock tables,alter on zm.* to 'zmuser'@'localhost' identified by 'zmpass';"
# Activate CGI
a2enmod cgi
# Activate modrewrite
a2enmod rewrite
# Restart apache # Restart apache
service apache2 restart service apache2 restart

67
utils/mk_bigfont.pl Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env perl
#
# ==========================================================================
#
# ZoneMinder Big Font Generate Script
# Copyright (C) 2015 Robin Därmann
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# ==========================================================================
# Basically, this script reads src/zm_font.h and duplicates every bit of every
# character found in that file. It then duplicates every generated line, so
# that every character effectively gets double sized.
# Output goes to STDOUT so it would be useful to redirect it to a file, i.e. to
# src/zm_bigfont.c
use strict;
use warnings;
my $in_head = 1;
open F, '<', '../src/zm_font.h';
print <<EOHEAD;
/***********************************************************/
/* */
/* Font file generated by schrorg */
/* based on the font file generated by rthelen */
/* using utils/mk_bigfont.pl */
/* */
/***********************************************************/
EOHEAD
while (my $line = <F>) {
$in_head-- if $line =~ /^$/ and $in_head;
next while $in_head;
unless ($line =~ /^\s+(0x..), \/\* (........)/) {
$line =~ s/static unsigned char fontdata/static unsigned int bigfontdata/;
print $line;
next;
}
my $code = $1;
my $bincode = $2;
$bincode = "$1$1$2$2$3$3$4$4$5$5$6$6$7$7$8$8" if $bincode =~ /(.)(.)(.)(.)(.)(.)(.)(.)$/;
$bincode =~ s/ /1/g;
my $intcode = unpack("N", pack("B32", substr("0" x 32 . $bincode, -32)));
my $hexcode = sprintf("%#x", $intcode);
$hexcode =~ s/^0$/0x0/;
$bincode =~ s/1/ /g;
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
print sprintf("\t%10s, /* %s */\n", $hexcode, $bincode);
}
close F;

View File

@ -26,12 +26,12 @@ App::uses('CacheEngine', 'Cache');
* You can configure Cache engines in your application's `bootstrap.php` file. A sample configuration would * You can configure Cache engines in your application's `bootstrap.php` file. A sample configuration would
* be * be
* *
* {{{ * ```
* Cache::config('shared', array( * Cache::config('shared', array(
* 'engine' => 'Apc', * 'engine' => 'Apc',
* 'prefix' => 'my_app_' * 'prefix' => 'my_app_'
* )); * ));
* }}} * ```
* *
* This would configure an APC cache engine to the 'shared' alias. You could then read and write * This would configure an APC cache engine to the 'shared' alias. You could then read and write
* to that cache alias by using it for the `$config` parameter in the various Cache methods. In * to that cache alias by using it for the `$config` parameter in the various Cache methods. In
@ -113,11 +113,11 @@ class Cache {
* - `user` Used by Xcache. Username for XCache * - `user` Used by Xcache. Username for XCache
* - `password` Used by Xcache/Redis. Password for XCache/Redis * - `password` Used by Xcache/Redis. Password for XCache/Redis
* *
* @see app/Config/core.php for configuration settings
* @param string $name Name of the configuration * @param string $name Name of the configuration
* @param array $settings Optional associative array of settings passed to the engine * @param array $settings Optional associative array of settings passed to the engine
* @return array array(engine, settings) on success, false on failure * @return array array(engine, settings) on success, false on failure
* @throws CacheException * @throws CacheException
* @see app/Config/core.php for configuration settings
*/ */
public static function config($name = null, $settings = array()) { public static function config($name = null, $settings = array()) {
if (is_array($name)) { if (is_array($name)) {
@ -125,33 +125,33 @@ class Cache {
} }
$current = array(); $current = array();
if (isset(self::$_config[$name])) { if (isset(static::$_config[$name])) {
$current = self::$_config[$name]; $current = static::$_config[$name];
} }
if (!empty($settings)) { if (!empty($settings)) {
self::$_config[$name] = $settings + $current; static::$_config[$name] = $settings + $current;
} }
if (empty(self::$_config[$name]['engine'])) { if (empty(static::$_config[$name]['engine'])) {
return false; return false;
} }
if (!empty(self::$_config[$name]['groups'])) { if (!empty(static::$_config[$name]['groups'])) {
foreach (self::$_config[$name]['groups'] as $group) { foreach (static::$_config[$name]['groups'] as $group) {
self::$_groups[$group][] = $name; static::$_groups[$group][] = $name;
sort(self::$_groups[$group]); sort(static::$_groups[$group]);
self::$_groups[$group] = array_unique(self::$_groups[$group]); static::$_groups[$group] = array_unique(static::$_groups[$group]);
} }
} }
$engine = self::$_config[$name]['engine']; $engine = static::$_config[$name]['engine'];
if (!isset(self::$_engines[$name])) { if (!isset(static::$_engines[$name])) {
self::_buildEngine($name); static::_buildEngine($name);
$settings = self::$_config[$name] = self::settings($name); $settings = static::$_config[$name] = static::settings($name);
} elseif ($settings = self::set(self::$_config[$name], null, $name)) { } elseif ($settings = static::set(static::$_config[$name], null, $name)) {
self::$_config[$name] = $settings; static::$_config[$name] = $settings;
} }
return compact('engine', 'settings'); return compact('engine', 'settings');
} }
@ -160,11 +160,11 @@ class Cache {
* Finds and builds the instance of the required engine class. * Finds and builds the instance of the required engine class.
* *
* @param string $name Name of the config array that needs an engine instance built * @param string $name Name of the config array that needs an engine instance built
* @return boolean * @return bool
* @throws CacheException * @throws CacheException
*/ */
protected static function _buildEngine($name) { protected static function _buildEngine($name) {
$config = self::$_config[$name]; $config = static::$_config[$name];
list($plugin, $class) = pluginSplit($config['engine'], true); list($plugin, $class) = pluginSplit($config['engine'], true);
$cacheClass = $class . 'Engine'; $cacheClass = $class . 'Engine';
@ -176,12 +176,17 @@ class Cache {
if (!is_subclass_of($cacheClass, 'CacheEngine')) { if (!is_subclass_of($cacheClass, 'CacheEngine')) {
throw new CacheException(__d('cake_dev', 'Cache engines must use %s as a base class.', 'CacheEngine')); throw new CacheException(__d('cake_dev', 'Cache engines must use %s as a base class.', 'CacheEngine'));
} }
self::$_engines[$name] = new $cacheClass(); static::$_engines[$name] = new $cacheClass();
if (!self::$_engines[$name]->init($config)) { if (!static::$_engines[$name]->init($config)) {
throw new CacheException(__d('cake_dev', 'Cache engine %s is not properly configured.', $name)); $msg = __d(
'cake_dev',
'Cache engine "%s" is not properly configured. Ensure required extensions are installed, and credentials/permissions are correct',
$name
);
throw new CacheException($msg);
} }
if (self::$_engines[$name]->settings['probability'] && time() % self::$_engines[$name]->settings['probability'] === 0) { if (static::$_engines[$name]->settings['probability'] && time() % static::$_engines[$name]->settings['probability'] === 0) {
self::$_engines[$name]->gc(); static::$_engines[$name]->gc();
} }
return true; return true;
} }
@ -192,22 +197,22 @@ class Cache {
* @return array Array of configured Cache config names. * @return array Array of configured Cache config names.
*/ */
public static function configured() { public static function configured() {
return array_keys(self::$_config); return array_keys(static::$_config);
} }
/** /**
* Drops a cache engine. Deletes the cache configuration information * Drops a cache engine. Deletes the cache configuration information
* If the deleted configuration is the last configuration using an certain engine, * If the deleted configuration is the last configuration using a certain engine,
* the Engine instance is also unset. * the Engine instance is also unset.
* *
* @param string $name A currently configured cache config you wish to remove. * @param string $name A currently configured cache config you wish to remove.
* @return boolean success of the removal, returns false when the config does not exist. * @return bool success of the removal, returns false when the config does not exist.
*/ */
public static function drop($name) { public static function drop($name) {
if (!isset(self::$_config[$name])) { if (!isset(static::$_config[$name])) {
return false; return false;
} }
unset(self::$_config[$name], self::$_engines[$name]); unset(static::$_config[$name], static::$_engines[$name]);
return true; return true;
} }
@ -238,29 +243,29 @@ class Cache {
if (is_array($settings) && $value !== null) { if (is_array($settings) && $value !== null) {
$config = $value; $config = $value;
} }
if (!isset(self::$_config[$config]) || !isset(self::$_engines[$config])) { if (!isset(static::$_config[$config]) || !isset(static::$_engines[$config])) {
return false; return false;
} }
if (!empty($settings)) { if (!empty($settings)) {
self::$_reset = true; static::$_reset = true;
} }
if (self::$_reset === true) { if (static::$_reset === true) {
if (empty($settings)) { if (empty($settings)) {
self::$_reset = false; static::$_reset = false;
$settings = self::$_config[$config]; $settings = static::$_config[$config];
} else { } else {
if (is_string($settings) && $value !== null) { if (is_string($settings) && $value !== null) {
$settings = array($settings => $value); $settings = array($settings => $value);
} }
$settings += self::$_config[$config]; $settings += static::$_config[$config];
if (isset($settings['duration']) && !is_numeric($settings['duration'])) { if (isset($settings['duration']) && !is_numeric($settings['duration'])) {
$settings['duration'] = strtotime($settings['duration']) - time(); $settings['duration'] = strtotime($settings['duration']) - time();
} }
} }
self::$_engines[$config]->settings = $settings; static::$_engines[$config]->settings = $settings;
} }
return self::settings($config); return static::settings($config);
} }
/** /**
@ -269,11 +274,11 @@ class Cache {
* Permanently remove all expired and deleted data * Permanently remove all expired and deleted data
* *
* @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default' * @param string $config [optional] The config name you wish to have garbage collected. Defaults to 'default'
* @param integer $expires [optional] An expires timestamp. Defaults to NULL * @param int $expires [optional] An expires timestamp. Defaults to NULL
* @return void * @return bool
*/ */
public static function gc($config = 'default', $expires = null) { public static function gc($config = 'default', $expires = null) {
self::$_engines[$config]->gc($expires); return static::$_engines[$config]->gc($expires);
} }
/** /**
@ -292,32 +297,32 @@ class Cache {
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached - anything except a resource * @param mixed $value Data to be cached - anything except a resource
* @param string $config Optional string configuration name to write to. Defaults to 'default' * @param string $config Optional string configuration name to write to. Defaults to 'default'
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public static function write($key, $value, $config = 'default') { public static function write($key, $value, $config = 'default') {
$settings = self::settings($config); $settings = static::settings($config);
if (empty($settings)) { if (empty($settings)) {
return false; return false;
} }
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$key = self::$_engines[$config]->key($key); $key = static::$_engines[$config]->key($key);
if (!$key || is_resource($value)) { if (!$key || is_resource($value)) {
return false; return false;
} }
$success = self::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']); $success = static::$_engines[$config]->write($settings['prefix'] . $key, $value, $settings['duration']);
self::set(null, $config); static::set(null, $config);
if ($success === false && $value !== '') { if ($success === false && $value !== '') {
trigger_error( trigger_error(
__d('cake_dev', __d('cake_dev',
"%s cache was unable to write '%s' to %s cache", "%s cache was unable to write '%s' to %s cache",
$config, $config,
$key, $key,
self::$_engines[$config]->settings['engine'] static::$_engines[$config]->settings['engine']
), ),
E_USER_WARNING E_USER_WARNING
); );
@ -343,46 +348,46 @@ class Cache {
* @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
*/ */
public static function read($key, $config = 'default') { public static function read($key, $config = 'default') {
$settings = self::settings($config); $settings = static::settings($config);
if (empty($settings)) { if (empty($settings)) {
return false; return false;
} }
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$key = self::$_engines[$config]->key($key); $key = static::$_engines[$config]->key($key);
if (!$key) { if (!$key) {
return false; return false;
} }
return self::$_engines[$config]->read($settings['prefix'] . $key); return static::$_engines[$config]->read($settings['prefix'] . $key);
} }
/** /**
* Increment a number under the key and return incremented value. * Increment a number under the key and return incremented value.
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to add * @param int $offset How much to add
* @param string $config Optional string configuration name. Defaults to 'default' * @param string $config Optional string configuration name. Defaults to 'default'
* @return mixed new value, or false if the data doesn't exist, is not integer, * @return mixed new value, or false if the data doesn't exist, is not integer,
* or if there was an error fetching it. * or if there was an error fetching it.
*/ */
public static function increment($key, $offset = 1, $config = 'default') { public static function increment($key, $offset = 1, $config = 'default') {
$settings = self::settings($config); $settings = static::settings($config);
if (empty($settings)) { if (empty($settings)) {
return false; return false;
} }
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$key = self::$_engines[$config]->key($key); $key = static::$_engines[$config]->key($key);
if (!$key || !is_int($offset) || $offset < 0) { if (!$key || !is_int($offset) || $offset < 0) {
return false; return false;
} }
$success = self::$_engines[$config]->increment($settings['prefix'] . $key, $offset); $success = static::$_engines[$config]->increment($settings['prefix'] . $key, $offset);
self::set(null, $config); static::set(null, $config);
return $success; return $success;
} }
@ -390,27 +395,27 @@ class Cache {
* Decrement a number under the key and return decremented value. * Decrement a number under the key and return decremented value.
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @param string $config Optional string configuration name. Defaults to 'default' * @param string $config Optional string configuration name. Defaults to 'default'
* @return mixed new value, or false if the data doesn't exist, is not integer, * @return mixed new value, or false if the data doesn't exist, is not integer,
* or if there was an error fetching it * or if there was an error fetching it
*/ */
public static function decrement($key, $offset = 1, $config = 'default') { public static function decrement($key, $offset = 1, $config = 'default') {
$settings = self::settings($config); $settings = static::settings($config);
if (empty($settings)) { if (empty($settings)) {
return false; return false;
} }
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$key = self::$_engines[$config]->key($key); $key = static::$_engines[$config]->key($key);
if (!$key || !is_int($offset) || $offset < 0) { if (!$key || !is_int($offset) || $offset < 0) {
return false; return false;
} }
$success = self::$_engines[$config]->decrement($settings['prefix'] . $key, $offset); $success = static::$_engines[$config]->decrement($settings['prefix'] . $key, $offset);
self::set(null, $config); static::set(null, $config);
return $success; return $success;
} }
@ -429,40 +434,40 @@ class Cache {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param string $config name of the configuration to use. Defaults to 'default' * @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public static function delete($key, $config = 'default') { public static function delete($key, $config = 'default') {
$settings = self::settings($config); $settings = static::settings($config);
if (empty($settings)) { if (empty($settings)) {
return false; return false;
} }
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$key = self::$_engines[$config]->key($key); $key = static::$_engines[$config]->key($key);
if (!$key) { if (!$key) {
return false; return false;
} }
$success = self::$_engines[$config]->delete($settings['prefix'] . $key); $success = static::$_engines[$config]->delete($settings['prefix'] . $key);
self::set(null, $config); static::set(null, $config);
return $success; return $success;
} }
/** /**
* Delete all keys from the cache. * Delete all keys from the cache.
* *
* @param boolean $check if true will check expiration, otherwise delete all * @param bool $check if true will check expiration, otherwise delete all
* @param string $config name of the configuration to use. Defaults to 'default' * @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean True if the cache was successfully cleared, false otherwise * @return bool True if the cache was successfully cleared, false otherwise
*/ */
public static function clear($check = false, $config = 'default') { public static function clear($check = false, $config = 'default') {
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$success = self::$_engines[$config]->clear($check); $success = static::$_engines[$config]->clear($check);
self::set(null, $config); static::set(null, $config);
return $success; return $success;
} }
@ -471,14 +476,14 @@ class Cache {
* *
* @param string $group name of the group to be cleared * @param string $group name of the group to be cleared
* @param string $config name of the configuration to use. Defaults to 'default' * @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean True if the cache group was successfully cleared, false otherwise * @return bool True if the cache group was successfully cleared, false otherwise
*/ */
public static function clearGroup($group, $config = 'default') { public static function clearGroup($group, $config = 'default') {
if (!self::isInitialized($config)) { if (!static::isInitialized($config)) {
return false; return false;
} }
$success = self::$_engines[$config]->clearGroup($group); $success = static::$_engines[$config]->clearGroup($group);
self::set(null, $config); static::set(null, $config);
return $success; return $success;
} }
@ -486,13 +491,13 @@ class Cache {
* Check if Cache has initialized a working config for the given name. * Check if Cache has initialized a working config for the given name.
* *
* @param string $config name of the configuration to use. Defaults to 'default' * @param string $config name of the configuration to use. Defaults to 'default'
* @return boolean Whether or not the config name has been initialized. * @return bool Whether or not the config name has been initialized.
*/ */
public static function isInitialized($config = 'default') { public static function isInitialized($config = 'default') {
if (Configure::read('Cache.disable')) { if (Configure::read('Cache.disable')) {
return false; return false;
} }
return isset(self::$_engines[$config]); return isset(static::$_engines[$config]);
} }
/** /**
@ -503,8 +508,8 @@ class Cache {
* @see Cache::config() * @see Cache::config()
*/ */
public static function settings($name = 'default') { public static function settings($name = 'default') {
if (!empty(self::$_engines[$name])) { if (!empty(static::$_engines[$name])) {
return self::$_engines[$name]->settings(); return static::$_engines[$name]->settings();
} }
return array(); return array();
} }
@ -512,7 +517,7 @@ class Cache {
/** /**
* Retrieve group names to config mapping. * Retrieve group names to config mapping.
* *
* {{{ * ```
* Cache::config('daily', array( * Cache::config('daily', array(
* 'duration' => '1 day', 'groups' => array('posts') * 'duration' => '1 day', 'groups' => array('posts')
* )); * ));
@ -520,7 +525,7 @@ class Cache {
* 'duration' => '1 week', 'groups' => array('posts', 'archive') * 'duration' => '1 week', 'groups' => array('posts', 'archive')
* )); * ));
* $configs = Cache::groupConfigs('posts'); * $configs = Cache::groupConfigs('posts');
* }}} * ```
* *
* $config will equal to `array('posts' => array('daily', 'weekly'))` * $config will equal to `array('posts' => array('daily', 'weekly'))`
* *
@ -530,10 +535,10 @@ class Cache {
*/ */
public static function groupConfigs($group = null) { public static function groupConfigs($group = null) {
if ($group === null) { if ($group === null) {
return self::$_groups; return static::$_groups;
} }
if (isset(self::$_groups[$group])) { if (isset(static::$_groups[$group])) {
return array($group => self::$_groups[$group]); return array($group => static::$_groups[$group]);
} }
throw new CacheException(__d('cake_dev', 'Invalid cache group %s', $group)); throw new CacheException(__d('cake_dev', 'Invalid cache group %s', $group));
} }
@ -549,27 +554,66 @@ class Cache {
* *
* Using a Closure to provide data, assume $this is a Model: * Using a Closure to provide data, assume $this is a Model:
* *
* {{{ * ```
* $model = $this; * $model = $this;
* $results = Cache::remember('all_articles', function() use ($model) { * $results = Cache::remember('all_articles', function() use ($model) {
* return $model->find('all'); * return $model->find('all');
* }); * });
* }}} * ```
* *
* @param string $key The cache key to read/store data at. * @param string $key The cache key to read/store data at.
* @param callable $callable The callable that provides data in the case when * @param callable $callable The callable that provides data in the case when
* the cache key is empty. Can be any callable type supported by your PHP. * the cache key is empty. Can be any callable type supported by your PHP.
* @param string $config The cache configuration to use for this operation. * @param string $config The cache configuration to use for this operation.
* Defaults to default. * Defaults to default.
* @return mixed The results of the callable or unserialized results.
*/ */
public static function remember($key, $callable, $config = 'default') { public static function remember($key, $callable, $config = 'default') {
$existing = self::read($key, $config); $existing = static::read($key, $config);
if ($existing !== false) { if ($existing !== false) {
return $existing; return $existing;
} }
$results = call_user_func($callable); $results = call_user_func($callable);
self::write($key, $results, $config); static::write($key, $results, $config);
return $results; return $results;
} }
/**
* Write data for key into a cache engine if it doesn't exist already.
*
* ### Usage:
*
* Writing to the active cache config:
*
* `Cache::add('cached_data', $data);`
*
* Writing to a specific cache config:
*
* `Cache::add('cached_data', $data, 'long_term');`
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached - anything except a resource.
* @param string $config Optional string configuration name to write to. Defaults to 'default'.
* @return bool True if the data was successfully cached, false on failure.
* Or if the key existed already.
*/
public static function add($key, $value, $config = 'default') {
$settings = self::settings($config);
if (empty($settings)) {
return false;
}
if (!self::isInitialized($config)) {
return false;
}
$key = self::$_engines[$config]->key($key);
if (!$key || is_resource($value)) {
return false;
}
$success = self::$_engines[$config]->add($settings['prefix'] . $key, $value, $settings['duration']);
self::set(null, $config);
return $success;
}
} }

View File

@ -42,7 +42,7 @@ abstract class CacheEngine {
* Called automatically by the cache frontend * Called automatically by the cache frontend
* *
* @param array $settings Associative array of parameters for the engine * @param array $settings Associative array of parameters for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
*/ */
public function init($settings = array()) { public function init($settings = array()) {
$settings += $this->settings + array( $settings += $this->settings + array(
@ -67,7 +67,7 @@ abstract class CacheEngine {
* *
* Permanently remove all expired and deleted data * Permanently remove all expired and deleted data
* *
* @param integer $expires [optional] An expires timestamp, invalidating all data before. * @param int $expires [optional] An expires timestamp, invalidating all data before.
* @return void * @return void
*/ */
public function gc($expires = null) { public function gc($expires = null) {
@ -78,11 +78,22 @@ abstract class CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache for. * @param int $duration How long to cache for.
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
abstract public function write($key, $value, $duration); abstract public function write($key, $value, $duration);
/**
* Write value for a key into cache if it doesn't already exist
*
* @param string $key Identifier for the data
* @param mixed $value Data to be cached
* @param int $duration How long to cache for.
* @return bool True if the data was successfully cached, false on failure
*/
public function add($key, $value, $duration) {
}
/** /**
* Read a key from the cache * Read a key from the cache
* *
@ -95,7 +106,7 @@ abstract class CacheEngine {
* Increment a number under the key and return incremented value * Increment a number under the key and return incremented value
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to add * @param int $offset How much to add
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
*/ */
abstract public function increment($key, $offset = 1); abstract public function increment($key, $offset = 1);
@ -104,7 +115,7 @@ abstract class CacheEngine {
* Decrement a number under the key and return decremented value * Decrement a number under the key and return decremented value
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
*/ */
abstract public function decrement($key, $offset = 1); abstract public function decrement($key, $offset = 1);
@ -113,15 +124,15 @@ abstract class CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
abstract public function delete($key); abstract public function delete($key);
/** /**
* Delete all keys from the cache * Delete all keys from the cache
* *
* @param boolean $check if true will check expiration, otherwise delete all * @param bool $check if true will check expiration, otherwise delete all
* @return boolean True if the cache was successfully cleared, false otherwise * @return bool True if the cache was successfully cleared, false otherwise
*/ */
abstract public function clear($check); abstract public function clear($check);
@ -130,8 +141,8 @@ abstract class CacheEngine {
* to decide whether actually delete the keys or just simulate it to achieve * to decide whether actually delete the keys or just simulate it to achieve
* the same result. * the same result.
* *
* @param string $groups name of the group to be cleared * @param string $group name of the group to be cleared
* @return boolean * @return bool
*/ */
public function clearGroup($group) { public function clearGroup($group) {
return false; return false;
@ -176,5 +187,4 @@ abstract class CacheEngine {
$key = preg_replace('/[\s]+/', '_', strtolower(trim(str_replace(array(DS, '/', '.'), '_', strval($key))))); $key = preg_replace('/[\s]+/', '_', strtolower(trim(str_replace(array(DS, '/', '.'), '_', strval($key)))));
return $prefix . $key; return $prefix . $key;
} }
} }

View File

@ -38,7 +38,7 @@ class ApcEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
* @see CacheEngine::__defaults * @see CacheEngine::__defaults
*/ */
public function init($settings = array()) { public function init($settings = array()) {
@ -55,8 +55,8 @@ class ApcEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
$expires = 0; $expires = 0;
@ -75,7 +75,7 @@ class ApcEngine extends CacheEngine {
*/ */
public function read($key) { public function read($key) {
$time = time(); $time = time();
$cachetime = intval(apc_fetch($key . '_expires')); $cachetime = (int)apc_fetch($key . '_expires');
if ($cachetime !== 0 && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { if ($cachetime !== 0 && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
return false; return false;
} }
@ -86,7 +86,7 @@ class ApcEngine extends CacheEngine {
* Increments the value of an integer cached key * Increments the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
*/ */
public function increment($key, $offset = 1) { public function increment($key, $offset = 1) {
@ -97,7 +97,7 @@ class ApcEngine extends CacheEngine {
* Decrements the value of an integer cached key * Decrements the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
*/ */
public function decrement($key, $offset = 1) { public function decrement($key, $offset = 1) {
@ -108,7 +108,7 @@ class ApcEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return apc_delete($key); return apc_delete($key);
@ -117,18 +117,25 @@ class ApcEngine extends CacheEngine {
/** /**
* Delete all keys from the cache. This will clear every cache config using APC. * Delete all keys from the cache. This will clear every cache config using APC.
* *
* @param boolean $check If true, nothing will be cleared, as entries are removed * @param bool $check If true, nothing will be cleared, as entries are removed
* from APC as they expired. This flag is really only used by FileEngine. * from APC as they expired. This flag is really only used by FileEngine.
* @return boolean True Returns true. * @return bool True Returns true.
*/ */
public function clear($check) { public function clear($check) {
if ($check) { if ($check) {
return true; return true;
} }
$info = apc_cache_info('user'); if (class_exists('APCIterator', false)) {
$cacheKeys = $info['cache_list']; $iterator = new APCIterator(
unset($info); 'user',
foreach ($cacheKeys as $key) { '/^' . preg_quote($this->settings['prefix'], '/') . '/',
APC_ITER_NONE
);
apc_delete($iterator);
return true;
}
$cache = apc_cache_info('user');
foreach ($cache['cache_list'] as $key) {
if (strpos($key['info'], $this->settings['prefix']) === 0) { if (strpos($key['info'], $this->settings['prefix']) === 0) {
apc_delete($key['info']); apc_delete($key['info']);
} }
@ -173,11 +180,30 @@ class ApcEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
apc_inc($this->settings['prefix'] . $group, 1, $success); apc_inc($this->settings['prefix'] . $group, 1, $success);
return $success; return $success;
} }
/**
* Write data for key into cache if it doesn't exist already.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
* @link http://php.net/manual/en/function.apc-add.php
*/
public function add($key, $value, $duration) {
$expires = 0;
if ($duration) {
$expires = time() + $duration;
}
apc_add($key . '_expires', $expires, $duration);
return apc_add($key, $value, $duration);
}
} }

View File

@ -53,7 +53,7 @@ class FileEngine extends CacheEngine {
/** /**
* True unless FileEngine::__active(); fails * True unless FileEngine::__active(); fails
* *
* @var boolean * @var bool
*/ */
protected $_init = true; protected $_init = true;
@ -64,7 +64,7 @@ class FileEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
*/ */
public function init($settings = array()) { public function init($settings = array()) {
$settings += array( $settings += array(
@ -93,8 +93,8 @@ class FileEngine extends CacheEngine {
/** /**
* Garbage collection. Permanently remove all expired and deleted data * Garbage collection. Permanently remove all expired and deleted data
* *
* @param integer $expires [optional] An expires timestamp, invalidating all data before. * @param int $expires [optional] An expires timestamp, invalidating all data before.
* @return boolean True if garbage collection was successful, false on failure * @return bool True if garbage collection was successful, false on failure
*/ */
public function gc($expires = null) { public function gc($expires = null) {
return $this->clear(true); return $this->clear(true);
@ -105,11 +105,11 @@ class FileEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $data Data to be cached * @param mixed $data Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $data, $duration) { public function write($key, $data, $duration) {
if ($data === '' || !$this->_init) { if (!$this->_init) {
return false; return false;
} }
@ -165,7 +165,7 @@ class FileEngine extends CacheEngine {
$this->_File->rewind(); $this->_File->rewind();
$time = time(); $time = time();
$cachetime = intval($this->_File->current()); $cachetime = (int)$this->_File->current();
if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) { if ($cachetime !== false && ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime)) {
if ($this->settings['lock']) { if ($this->settings['lock']) {
@ -200,7 +200,7 @@ class FileEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
if ($this->_setKey($key) === false || !$this->_init) { if ($this->_setKey($key) === false || !$this->_init) {
@ -217,8 +217,8 @@ class FileEngine extends CacheEngine {
/** /**
* Delete all values from the cache * Delete all values from the cache
* *
* @param boolean $check Optional - only delete expired cache items * @param bool $check Optional - only delete expired cache items
* @return boolean True if the cache was successfully cleared, false otherwise * @return bool True if the cache was successfully cleared, false otherwise
*/ */
public function clear($check) { public function clear($check) {
if (!$this->_init) { if (!$this->_init) {
@ -255,8 +255,8 @@ class FileEngine extends CacheEngine {
* Used to clear a directory of matching files. * Used to clear a directory of matching files.
* *
* @param string $path The path to search. * @param string $path The path to search.
* @param integer $now The current timestamp * @param int $now The current timestamp
* @param integer $threshold Any file not modified after this value will be deleted. * @param int $threshold Any file not modified after this value will be deleted.
* @return void * @return void
*/ */
protected function _clearDirectory($path, $now, $threshold) { protected function _clearDirectory($path, $now, $threshold) {
@ -271,11 +271,12 @@ class FileEngine extends CacheEngine {
if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) { if (substr($entry, 0, $prefixLength) !== $this->settings['prefix']) {
continue; continue;
} }
$filePath = $path . $entry;
if (!file_exists($filePath) || is_dir($filePath)) { try {
$file = new SplFileObject($path . $entry, 'r');
} catch (Exception $e) {
continue; continue;
} }
$file = new SplFileObject($path . $entry, 'r');
if ($threshold) { if ($threshold) {
$mtime = $file->getMTime(); $mtime = $file->getMTime();
@ -303,8 +304,8 @@ class FileEngine extends CacheEngine {
/** /**
* Not implemented * Not implemented
* *
* @param string $key * @param string $key The key to decrement
* @param integer $offset * @param int $offset The number to offset
* @return void * @return void
* @throws CacheException * @throws CacheException
*/ */
@ -315,8 +316,8 @@ class FileEngine extends CacheEngine {
/** /**
* Not implemented * Not implemented
* *
* @param string $key * @param string $key The key to decrement
* @param integer $offset * @param int $offset The number to offset
* @return void * @return void
* @throws CacheException * @throws CacheException
*/ */
@ -329,8 +330,8 @@ class FileEngine extends CacheEngine {
* for the cache file the key is referring to. * for the cache file the key is referring to.
* *
* @param string $key The key * @param string $key The key
* @param boolean $createKey Whether the key should be created if it doesn't exists, or not * @param bool $createKey Whether the key should be created if it doesn't exists, or not
* @return boolean true if the cache key could be set, false otherwise * @return bool true if the cache key could be set, false otherwise
*/ */
protected function _setKey($key, $createKey = false) { protected function _setKey($key, $createKey = false) {
$groups = null; $groups = null;
@ -369,7 +370,7 @@ class FileEngine extends CacheEngine {
/** /**
* Determine is cache directory is writable * Determine is cache directory is writable
* *
* @return boolean * @return bool
*/ */
protected function _active() { protected function _active() {
$dir = new SplFileInfo($this->settings['path']); $dir = new SplFileInfo($this->settings['path']);
@ -405,7 +406,8 @@ class FileEngine extends CacheEngine {
/** /**
* Recursively deletes all files under any directory named as $group * Recursively deletes all files under any directory named as $group
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
$this->_File = null; $this->_File = null;
@ -427,4 +429,21 @@ class FileEngine extends CacheEngine {
} }
return true; return true;
} }
/**
* Write data for key into cache if it doesn't exist already.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
*/
public function add($key, $value, $duration) {
$cachedValue = $this->read($key);
if ($cachedValue === false) {
return $this->write($key, $value, $duration);
}
return false;
}
} }

View File

@ -22,7 +22,7 @@
* more information. * more information.
* *
* @package Cake.Cache.Engine * @package Cake.Cache.Engine
* @deprecated You should use the Memcached adapter instead. * @deprecated 3.0.0 You should use the Memcached adapter instead.
*/ */
class MemcacheEngine extends CacheEngine { class MemcacheEngine extends CacheEngine {
@ -59,7 +59,7 @@ class MemcacheEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
*/ */
public function init($settings = array()) { public function init($settings = array()) {
if (!class_exists('Memcache')) { if (!class_exists('Memcache')) {
@ -104,7 +104,7 @@ class MemcacheEngine extends CacheEngine {
* @return array Array containing host, port * @return array Array containing host, port
*/ */
protected function _parseServerString($server) { protected function _parseServerString($server) {
if ($server[0] === 'u') { if (strpos($server, 'unix://') === 0) {
return array($server, 0); return array($server, 0);
} }
if (substr($server, 0, 1) === '[') { if (substr($server, 0, 1) === '[') {
@ -131,8 +131,8 @@ class MemcacheEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
* @see http://php.net/manual/en/memcache.set.php * @see http://php.net/manual/en/memcache.set.php
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
@ -156,7 +156,7 @@ class MemcacheEngine extends CacheEngine {
* Increments the value of an integer cached key * Increments the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
* @throws CacheException when you try to increment with compress = true * @throws CacheException when you try to increment with compress = true
*/ */
@ -173,7 +173,7 @@ class MemcacheEngine extends CacheEngine {
* Decrements the value of an integer cached key * Decrements the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
* @throws CacheException when you try to decrement with compress = true * @throws CacheException when you try to decrement with compress = true
*/ */
@ -190,7 +190,7 @@ class MemcacheEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return $this->_Memcache->delete($key); return $this->_Memcache->delete($key);
@ -199,8 +199,9 @@ class MemcacheEngine extends CacheEngine {
/** /**
* Delete all keys from the cache * Delete all keys from the cache
* *
* @param boolean $check * @param bool $check If true no deletes will occur and instead CakePHP will rely
* @return boolean True if the cache was successfully cleared, false otherwise * on key TTL values.
* @return bool True if the cache was successfully cleared, false otherwise
*/ */
public function clear($check) { public function clear($check) {
if ($check) { if ($check) {
@ -231,8 +232,8 @@ class MemcacheEngine extends CacheEngine {
* Connects to a server in connection pool * Connects to a server in connection pool
* *
* @param string $host host ip address or name * @param string $host host ip address or name
* @param integer $port Server port * @param int $port Server port
* @return boolean True if memcache server was connected * @return bool True if memcache server was connected
*/ */
public function connect($host, $port = 11211) { public function connect($host, $port = 11211) {
if ($this->_Memcache->getServerStatus($host, $port) === 0) { if ($this->_Memcache->getServerStatus($host, $port) === 0) {
@ -282,9 +283,30 @@ class MemcacheEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
return (bool)$this->_Memcache->increment($this->settings['prefix'] . $group); return (bool)$this->_Memcache->increment($this->settings['prefix'] . $group);
} }
/**
* Write data for key into cache if it doesn't exist already. When using memcached as your cache engine
* remember that the Memcached PECL extension does not support cache expiry times greater
* than 30 days in the future. Any duration greater than 30 days will be treated as never expiring.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
* @link http://php.net/manual/en/memcache.add.php
*/
public function add($key, $value, $duration) {
if ($duration > 30 * DAY) {
$duration = 0;
}
return $this->_Memcache->add($key, $value, $this->settings['compress'], $duration);
}
} }

69
web/api/lib/Cake/Cache/Engine/MemcachedEngine.php Executable file → Normal file
View File

@ -45,6 +45,8 @@ class MemcachedEngine extends CacheEngine {
* - serialize = string, default => php. The serializer engine used to serialize data. * - serialize = string, default => php. The serializer engine used to serialize data.
* Available engines are php, igbinary and json. Beside php, the memcached extension * Available engines are php, igbinary and json. Beside php, the memcached extension
* must be compiled with the appropriate serializer support. * must be compiled with the appropriate serializer support.
* - options - Additional options for the memcached client. Should be an array of option => value.
* Use the Memcached::OPT_* constants as keys.
* *
* @var array * @var array
*/ */
@ -70,7 +72,7 @@ class MemcachedEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
* @throws CacheException when you try use authentication without Memcached compiled with SASL support * @throws CacheException when you try use authentication without Memcached compiled with SASL support
*/ */
public function init($settings = array()) { public function init($settings = array()) {
@ -92,7 +94,8 @@ class MemcachedEngine extends CacheEngine {
'persistent' => false, 'persistent' => false,
'login' => null, 'login' => null,
'password' => null, 'password' => null,
'serialize' => 'php' 'serialize' => 'php',
'options' => array()
); );
parent::init($settings); parent::init($settings);
@ -104,7 +107,11 @@ class MemcachedEngine extends CacheEngine {
return true; return true;
} }
$this->_Memcached = new Memcached($this->settings['persistent'] ? (string)$this->settings['persistent'] : null); if (!$this->settings['persistent']) {
$this->_Memcached = new Memcached();
} else {
$this->_Memcached = new Memcached((string)$this->settings['persistent']);
}
$this->_setOptions(); $this->_setOptions();
if (count($this->_Memcached->getServerList())) { if (count($this->_Memcached->getServerList())) {
@ -126,8 +133,14 @@ class MemcachedEngine extends CacheEngine {
__d('cake_dev', 'Memcached extension is not build with SASL support') __d('cake_dev', 'Memcached extension is not build with SASL support')
); );
} }
$this->_Memcached->setOption(Memcached::OPT_BINARY_PROTOCOL, true);
$this->_Memcached->setSaslAuthData($this->settings['login'], $this->settings['password']); $this->_Memcached->setSaslAuthData($this->settings['login'], $this->settings['password']);
} }
if (is_array($this->settings['options'])) {
foreach ($this->settings['options'] as $opt => $value) {
$this->_Memcached->setOption($opt, $value);
}
}
return true; return true;
} }
@ -136,6 +149,7 @@ class MemcachedEngine extends CacheEngine {
* Settings the memcached instance * Settings the memcached instance
* *
* @throws CacheException when the Memcached extension is not built with the desired serializer engine * @throws CacheException when the Memcached extension is not built with the desired serializer engine
* @return void
*/ */
protected function _setOptions() { protected function _setOptions() {
$this->_Memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); $this->_Memcached->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true);
@ -171,8 +185,9 @@ class MemcachedEngine extends CacheEngine {
* @return array Array containing host, port * @return array Array containing host, port
*/ */
protected function _parseServerString($server) { protected function _parseServerString($server) {
if ($server[0] === 'u') { $socketTransport = 'unix://';
return array($server, 0); if (strpos($server, $socketTransport) === 0) {
return array(substr($server, strlen($socketTransport)), 0);
} }
if (substr($server, 0, 1) === '[') { if (substr($server, 0, 1) === '[') {
$position = strpos($server, ']:'); $position = strpos($server, ']:');
@ -193,13 +208,13 @@ class MemcachedEngine extends CacheEngine {
/** /**
* Write data for key into cache. When using memcached as your cache engine * Write data for key into cache. When using memcached as your cache engine
* remember that the Memcached pecl extension does not support cache expiry times greater * remember that the Memcached PECL extension does not support cache expiry times greater
* than 30 days in the future. Any duration greater than 30 days will be treated as never expiring. * than 30 days in the future. Any duration greater than 30 days will be treated as never expiring.
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
* @see http://php.net/manual/en/memcache.set.php * @see http://php.net/manual/en/memcache.set.php
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
@ -224,7 +239,7 @@ class MemcachedEngine extends CacheEngine {
* Increments the value of an integer cached key * Increments the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
* @throws CacheException when you try to increment with compress = true * @throws CacheException when you try to increment with compress = true
*/ */
@ -236,7 +251,7 @@ class MemcachedEngine extends CacheEngine {
* Decrements the value of an integer cached key * Decrements the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
* @throws CacheException when you try to decrement with compress = true * @throws CacheException when you try to decrement with compress = true
*/ */
@ -248,7 +263,7 @@ class MemcachedEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return $this->_Memcached->delete($key); return $this->_Memcached->delete($key);
@ -257,8 +272,10 @@ class MemcachedEngine extends CacheEngine {
/** /**
* Delete all keys from the cache * Delete all keys from the cache
* *
* @param boolean $check * @param bool $check If true no deletes will occur and instead CakePHP will rely
* @return boolean True if the cache was successfully cleared, false otherwise * on key TTL values.
* @return bool True if the cache was successfully cleared, false otherwise. Will
* also return false if you are using a binary protocol.
*/ */
public function clear($check) { public function clear($check) {
if ($check) { if ($check) {
@ -266,6 +283,9 @@ class MemcachedEngine extends CacheEngine {
} }
$keys = $this->_Memcached->getAllKeys(); $keys = $this->_Memcached->getAllKeys();
if ($keys === false) {
return false;
}
foreach ($keys as $key) { foreach ($keys as $key) {
if (strpos($key, $this->settings['prefix']) === 0) { if (strpos($key, $this->settings['prefix']) === 0) {
@ -314,9 +334,30 @@ class MemcachedEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
return (bool)$this->_Memcached->increment($this->settings['prefix'] . $group); return (bool)$this->_Memcached->increment($this->settings['prefix'] . $group);
} }
/**
* Write data for key into cache if it doesn't exist already. When using memcached as your cache engine
* remember that the Memcached pecl extension does not support cache expiry times greater
* than 30 days in the future. Any duration greater than 30 days will be treated as never expiring.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
* @link http://php.net/manual/en/memcached.add.php
*/
public function add($key, $value, $duration) {
if ($duration > 30 * DAY) {
$duration = 0;
}
return $this->_Memcached->add($key, $value, $duration);
}
} }

View File

@ -38,6 +38,7 @@ class RedisEngine extends CacheEngine {
* - port = integer port number to the Redis server (default: 6379) * - port = integer port number to the Redis server (default: 6379)
* - timeout = float timeout in seconds (default: 0) * - timeout = float timeout in seconds (default: 0)
* - persistent = boolean Connects to the Redis server with a persistent connection (default: true) * - persistent = boolean Connects to the Redis server with a persistent connection (default: true)
* - unix_socket = path to the unix socket file (default: false)
* *
* @var array * @var array
*/ */
@ -50,7 +51,7 @@ class RedisEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
*/ */
public function init($settings = array()) { public function init($settings = array()) {
if (!class_exists('Redis')) { if (!class_exists('Redis')) {
@ -58,13 +59,14 @@ class RedisEngine extends CacheEngine {
} }
parent::init(array_merge(array( parent::init(array_merge(array(
'engine' => 'Redis', 'engine' => 'Redis',
'prefix' => null, 'prefix' => Inflector::slug(APP_DIR) . '_',
'server' => '127.0.0.1', 'server' => '127.0.0.1',
'database' => 0, 'database' => 0,
'port' => 6379, 'port' => 6379,
'password' => false, 'password' => false,
'timeout' => 0, 'timeout' => 0,
'persistent' => true 'persistent' => true,
'unix_socket' => false
), $settings) ), $settings)
); );
@ -74,28 +76,29 @@ class RedisEngine extends CacheEngine {
/** /**
* Connects to a Redis server * Connects to a Redis server
* *
* @return boolean True if Redis server was connected * @return bool True if Redis server was connected
*/ */
protected function _connect() { protected function _connect() {
$return = false;
try { try {
$this->_Redis = new Redis(); $this->_Redis = new Redis();
if (empty($this->settings['persistent'])) { if (!empty($this->settings['unix_socket'])) {
$return = $this->_Redis->connect($this->settings['unix_socket']);
} elseif (empty($this->settings['persistent'])) {
$return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']); $return = $this->_Redis->connect($this->settings['server'], $this->settings['port'], $this->settings['timeout']);
} else { } else {
$persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database']; $persistentId = $this->settings['port'] . $this->settings['timeout'] . $this->settings['database'];
$return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId); $return = $this->_Redis->pconnect($this->settings['server'], $this->settings['port'], $this->settings['timeout'], $persistentId);
} }
} catch (RedisException $e) { } catch (RedisException $e) {
$return = false;
}
if (!$return) {
return false; return false;
} }
if ($return && $this->settings['password']) { if ($this->settings['password'] && !$this->_Redis->auth($this->settings['password'])) {
$return = $this->_Redis->auth($this->settings['password']); return false;
} }
if ($return) { return $this->_Redis->select($this->settings['database']);
$return = $this->_Redis->select($this->settings['database']);
}
return $return;
} }
/** /**
@ -103,13 +106,18 @@ class RedisEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
if (!is_int($value)) { if (!is_int($value)) {
$value = serialize($value); $value = serialize($value);
} }
if (!$this->_Redis->isConnected()) {
$this->_connect();
}
if ($duration === 0) { if ($duration === 0) {
return $this->_Redis->set($key, $value); return $this->_Redis->set($key, $value);
} }
@ -138,7 +146,7 @@ class RedisEngine extends CacheEngine {
* Increments the value of an integer cached key * Increments the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
* @throws CacheException when you try to increment with compress = true * @throws CacheException when you try to increment with compress = true
*/ */
@ -150,7 +158,7 @@ class RedisEngine extends CacheEngine {
* Decrements the value of an integer cached key * Decrements the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
* @throws CacheException when you try to decrement with compress = true * @throws CacheException when you try to decrement with compress = true
*/ */
@ -162,7 +170,7 @@ class RedisEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return $this->_Redis->delete($key) > 0; return $this->_Redis->delete($key) > 0;
@ -171,8 +179,9 @@ class RedisEngine extends CacheEngine {
/** /**
* Delete all keys from the cache * Delete all keys from the cache
* *
* @param boolean $check * @param bool $check Whether or not expiration keys should be checked. If
* @return boolean True if the cache was successfully cleared, false otherwise * true, no keys will be removed as cache will rely on redis TTL's.
* @return bool True if the cache was successfully cleared, false otherwise
*/ */
public function clear($check) { public function clear($check) {
if ($check) { if ($check) {
@ -208,7 +217,8 @@ class RedisEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group name to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
return (bool)$this->_Redis->incr($this->settings['prefix'] . $group); return (bool)$this->_Redis->incr($this->settings['prefix'] . $group);
@ -222,4 +232,27 @@ class RedisEngine extends CacheEngine {
$this->_Redis->close(); $this->_Redis->close();
} }
} }
/**
* Write data for key into cache if it doesn't exist already.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
* @link https://github.com/phpredis/phpredis#setnx
*/
public function add($key, $value, $duration) {
if (!is_int($value)) {
$value = serialize($value);
}
$result = $this->_Redis->setnx($key, $value);
// setnx() doesn't have an expiry option, so overwrite the key with one
if ($result) {
return $this->_Redis->setex($key, $duration, $value);
}
return false;
}
} }

View File

@ -40,7 +40,7 @@ class WincacheEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
* @see CacheEngine::__defaults * @see CacheEngine::__defaults
*/ */
public function init($settings = array()) { public function init($settings = array()) {
@ -57,8 +57,8 @@ class WincacheEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
$expires = time() + $duration; $expires = time() + $duration;
@ -80,7 +80,7 @@ class WincacheEngine extends CacheEngine {
*/ */
public function read($key) { public function read($key) {
$time = time(); $time = time();
$cachetime = intval(wincache_ucache_get($key . '_expires')); $cachetime = (int)wincache_ucache_get($key . '_expires');
if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) { if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
return false; return false;
} }
@ -91,7 +91,7 @@ class WincacheEngine extends CacheEngine {
* Increments the value of an integer cached key * Increments the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
*/ */
public function increment($key, $offset = 1) { public function increment($key, $offset = 1) {
@ -102,7 +102,7 @@ class WincacheEngine extends CacheEngine {
* Decrements the value of an integer cached key * Decrements the value of an integer cached key
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
*/ */
public function decrement($key, $offset = 1) { public function decrement($key, $offset = 1) {
@ -113,7 +113,7 @@ class WincacheEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return wincache_ucache_delete($key); return wincache_ucache_delete($key);
@ -123,9 +123,9 @@ class WincacheEngine extends CacheEngine {
* Delete all keys from the cache. This will clear every * Delete all keys from the cache. This will clear every
* item in the cache matching the cache config prefix. * item in the cache matching the cache config prefix.
* *
* @param boolean $check If true, nothing will be cleared, as entries will * @param bool $check If true, nothing will be cleared, as entries will
* naturally expire in wincache.. * naturally expire in wincache..
* @return boolean True Returns true. * @return bool True Returns true.
*/ */
public function clear($check) { public function clear($check) {
if ($check) { if ($check) {
@ -179,7 +179,8 @@ class WincacheEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
$success = null; $success = null;
@ -187,4 +188,20 @@ class WincacheEngine extends CacheEngine {
return $success; return $success;
} }
/**
* Write data for key into cache if it doesn't exist already.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
*/
public function add($key, $value, $duration) {
$cachedValue = $this->read($key);
if ($cachedValue === false) {
return $this->write($key, $value, $duration);
}
return false;
}
} }

View File

@ -41,10 +41,10 @@ class XcacheEngine extends CacheEngine {
* To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array()); * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
* *
* @param array $settings array of setting for the engine * @param array $settings array of setting for the engine
* @return boolean True if the engine has been successfully initialized, false if not * @return bool True if the engine has been successfully initialized, false if not
*/ */
public function init($settings = array()) { public function init($settings = array()) {
if (php_sapi_name() !== 'cli') { if (PHP_SAPI !== 'cli') {
parent::init(array_merge(array( parent::init(array_merge(array(
'engine' => 'Xcache', 'engine' => 'Xcache',
'prefix' => Inflector::slug(APP_DIR) . '_', 'prefix' => Inflector::slug(APP_DIR) . '_',
@ -62,8 +62,8 @@ class XcacheEngine extends CacheEngine {
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param mixed $value Data to be cached * @param mixed $value Data to be cached
* @param integer $duration How long to cache the data, in seconds * @param int $duration How long to cache the data, in seconds
* @return boolean True if the data was successfully cached, false on failure * @return bool True if the data was successfully cached, false on failure
*/ */
public function write($key, $value, $duration) { public function write($key, $value, $duration) {
$expires = time() + $duration; $expires = time() + $duration;
@ -80,7 +80,7 @@ class XcacheEngine extends CacheEngine {
public function read($key) { public function read($key) {
if (xcache_isset($key)) { if (xcache_isset($key)) {
$time = time(); $time = time();
$cachetime = intval(xcache_get($key . '_expires')); $cachetime = (int)xcache_get($key . '_expires');
if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) { if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
return false; return false;
} }
@ -94,7 +94,7 @@ class XcacheEngine extends CacheEngine {
* If the cache key is not an integer it will be treated as 0 * If the cache key is not an integer it will be treated as 0
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to increment * @param int $offset How much to increment
* @return New incremented value, false otherwise * @return New incremented value, false otherwise
*/ */
public function increment($key, $offset = 1) { public function increment($key, $offset = 1) {
@ -106,7 +106,7 @@ class XcacheEngine extends CacheEngine {
* If the cache key is not an integer it will be treated as 0 * If the cache key is not an integer it will be treated as 0
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @param integer $offset How much to subtract * @param int $offset How much to subtract
* @return New decremented value, false otherwise * @return New decremented value, false otherwise
*/ */
public function decrement($key, $offset = 1) { public function decrement($key, $offset = 1) {
@ -117,7 +117,7 @@ class XcacheEngine extends CacheEngine {
* Delete a key from the cache * Delete a key from the cache
* *
* @param string $key Identifier for the data * @param string $key Identifier for the data
* @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
*/ */
public function delete($key) { public function delete($key) {
return xcache_unset($key); return xcache_unset($key);
@ -126,8 +126,9 @@ class XcacheEngine extends CacheEngine {
/** /**
* Delete all keys from the cache * Delete all keys from the cache
* *
* @param boolean $check * @param bool $check If true no deletes will occur and instead CakePHP will rely
* @return boolean True if the cache was successfully cleared, false otherwise * on key TTL values.
* @return bool True if the cache was successfully cleared, false otherwise
*/ */
public function clear($check) { public function clear($check) {
$this->_auth(); $this->_auth();
@ -163,7 +164,8 @@ class XcacheEngine extends CacheEngine {
* Increments the group value to simulate deletion of all keys under a group * Increments the group value to simulate deletion of all keys under a group
* old values will remain in storage until they expire. * old values will remain in storage until they expire.
* *
* @return boolean success * @param string $group The group to clear.
* @return bool success
*/ */
public function clearGroup($group) { public function clearGroup($group) {
return (bool)xcache_inc($this->settings['prefix'] . $group, 1); return (bool)xcache_inc($this->settings['prefix'] . $group, 1);
@ -176,7 +178,7 @@ class XcacheEngine extends CacheEngine {
* This has to be done because xcache_clear_cache() needs to pass Basic Http Auth * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth
* (see xcache.admin configuration settings) * (see xcache.admin configuration settings)
* *
* @param boolean $reverse Revert changes * @param bool $reverse Revert changes
* @return void * @return void
*/ */
protected function _auth($reverse = false) { protected function _auth($reverse = false) {
@ -205,4 +207,21 @@ class XcacheEngine extends CacheEngine {
} }
} }
} }
/**
* Write data for key into cache if it doesn't exist already.
* If it already exists, it fails and returns false.
*
* @param string $key Identifier for the data.
* @param mixed $value Data to be cached.
* @param int $duration How long to cache the data, in seconds.
* @return bool True if the data was successfully cached, false on failure.
*/
public function add($key, $value, $duration) {
$cachedValue = $this->read($key);
if ($cachedValue === false) {
return $this->write($key, $value, $duration);
}
return false;
}
} }

Some files were not shown because too many files have changed in this diff Show More