/onvif_simple_server

Light implementation of an onvif server intended for use in resource-constrained devices

Primary LanguageCGNU General Public License v3.0GPL-3.0

onvif_simple_server_e is a C light implementation of an onvif server intended for use in resource-constrained devices.

So:

  • no gsoap
  • no libxml

The XML parsing features are replaced by a wrapper that uses ezxml library and a template based strategy.

About security, you can choose between libtomcrypt or mbedtls, to handle authentication.

The web service discovery daemon and the notify server daemon are standalone programs and must be started with command line options.

The onvif server instead runs as CGI and therefore needs an http server that supports the CGI standard (for example httpd from busybox).

Table of Contents

Build

  • Open the Makefile and edit the path to the libtomcrypt library to suit your needs
  • Run make

Create a working example with lighttpd

  • Open extras folder
  • Customize build.sh script, if you want
  • Run ./build.sh
  • Copy the content of the _install folder to /usr/local
  • Run /usr/local/bin/lighttpd -f /usr/local/etc/lighttpd.conf
  • Run your preferred client and test the address http://YOUR_IP:8080/onvif/device_service

Configuration

onvif_simple_server

onvif_simple server supports the following options but you should use them just for debugging purpose

Usage: onvif_simple_server [-c CONF_FILE] [-d] [-f]

        -c CONF_FILE, --conf_file CONF_FILE
                path of the configuration file
        -d LEVEL, --debug LEVEL
                enable debug with LEVEL = 0..5 (default 0 = fatal errors)
        -f, --conf_help
                print the help for the configuration file
        -h, --help
                print this help
Option Description Example
conf_file the path of the file containing the configuration /etc/onvif_simple_server.conf
debug debug level from 0 to 5 -
conf_help print the help to create a configuration file -

The configuration file is shared between various programs. Below an example of the configuration file for a cam:

model=Yi Hack
manufacturer=Yi
firmware_ver=x.y.z
hardware_id=AFUS
serial_num=AFUSY12ABCDE3F456789
ifs=wlan0
port=80
scope=onvif://www.onvif.org/Profile/Streaming
user=
password=
#Advanced options
adv_fault_if_unknown=0
adv_synology_nvr=0

#Profile 0
name=Profile_0
width=1920
height=1080
url=rtsp://%s/ch0_0.h264
snapurl=http://%s/cgi-bin/snapshot.sh?res=high&watermark=yes
type=H264
decoder=G711

#Profile 1
name=Profile_1
width=640
height=360
url=rtsp://%s/ch0_1.h264
snapurl=http://%s/cgi-bin/snapshot.sh?res=low&watermark=yes
type=H264
decoder=NONE

#PTZ
ptz=1
get_position=/tmp/sd/yi-hack/bin/ipc_cmd -g
is_moving=/tmp/sd/yi-hack/bin/ipc_cmd -u
move_left=/tmp/sd/yi-hack/bin/ipc_cmd -m left
move_right=/tmp/sd/yi-hack/bin/ipc_cmd -m right
move_up=/tmp/sd/yi-hack/bin/ipc_cmd -m up
move_down=/tmp/sd/yi-hack/bin/ipc_cmd -m down
move_stop=/tmp/sd/yi-hack/bin/ipc_cmd -m stop
move_preset=/tmp/sd/yi-hack/bin/ipc_cmd -p %d
goto_home_position=/tmp/sd/yi-hack/bin/ipc_cmd -p 0
set_preset=/tmp/sd/yi-hack/script/ptz_presets.sh -a add_preset -m %s
set_home_position=/tmp/sd/yi-hack/script/ptz_presets.sh -a set_home_position
remove_preset=/tmp/sd/yi-hack/script/ptz_presets.sh -a del_preset -n %d
jump_to_abs=/tmp/sd/yi-hack/bin/ipc_cmd -j %f,%f
jump_to_rel=/tmp/sd/yi-hack/bin/ipc_cmd -J %f,%f
get_presets=/tmp/sd/yi-hack/script/ptz_presets.sh -a get_presets

#EVENT
events=1
#Event 0
topic=tns1:VideoSource/MotionAlarm
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/motion_alarm
#Event 1
topic=tns1:RuleEngine/MyRuleDetector/PeopleDetect
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/human_detection
#Event 2
topic=tns1:RuleEngine/MyRuleDetector/VehicleDetect
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/vehicle_detection
#Event 3
topic=tns1:RuleEngine/MyRuleDetector/DogCatDetect
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/animal_detection
#Event 4
topic=tns1:RuleEngine/MyRuleDetector/BabyCryingDetect
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/baby_crying
#Event 5
topic=tns1:AudioAnalytics/Audio/DetectedSound
source_name=VideoSourceConfigurationToken
source_value=VideoSourceToken
input_file=/tmp/onvif_notify_server/sound_detection

Note:

  • you can use 1 or 2 profiles.
  • ipc_cmd is just an example of a local binary that handles ptz, use the specific program of your cam
  • %s, %d and %f are placeholders replaced runtime with the proper parameter
  • use the same folder for the input files of the events

Please pay attention: the order of the lines must be respected. Don't mix them!

Brief explanation of some parameters:

Param Description
ifs the network interface used by your http server
port the TCP port used by your http server
user the user you want to set for WS-UsernameToken authentication, if blank security is disabled
adv_fault_if_unknown set to 1 if your ONVIF client is not able to connect to the device
adv_synology_nvr set to 1 if you are using a Synology NVR
url the url of your streaming service (it is not provided by onvif server)
snapurl the url of your snapshot service (tipically an http url that provides a jpg image)
decoder set to G711 or AAC if your device support an audio back channel
ptz 1 if onvif_simple_server can control PTZ, 0 otherwise
move_* the binary that moves the PTZ controls, onvif_simple_server will run it with a system call
events 1 if you want to enable events handling
topic the topic of the event
source_name the source name inside the Notify message
source_value the source value inside the Notify message
input_file the file created when the event is fired
events set to 1 to enable ONVIF PullPoint, 2 to enable WS Base Notification or 3 to enable both

Check the code for information.

wsd_simple_server

wsd_simple server supports the following options

Usage: wsd_simple_server -i INTERFACE -x XADDR [-m MODEL] [-n MANUFACTURER] -p PID_FILE [-f] [-d LEVEL]

        -i, --if_name
                network interface
        -x, --xaddr
                resource address
        -m, --model
                model name
        -n, --hardware
                hardware manufacturer
        -p, --pid_file
                pid file
        -f, --foreground
                don't daemonize
        -d LEVEL, --debug LEVEL
                enable debug with LEVEL = 0..5 (default 0 = log fatal errors)
        -h, --help
                print this help
Option Description Example
if_name the network interface that the device binds eth0
xaddr the resource address associated to the onvif server http://%s/onvif/device_service
pid_file is the pid file created by the daemon /var/run/wsd_simple_server.pid
foreground don't fork -
debug debug level from 0 to 5 -

%s is replaced runtime with the IP address of the device.

onvif_notify_server

onvif_notify_server checks the files related to the events and sends the notify message when an event is fired.

  • When the file is created a new notify message with state "true" is sent to all subscribers.
  • When the file is deleted a new notify message with state "false" is sent to all subscribers.
  • When a Synchronization Point is requested from an onvif client, a new Notify message with the current state is sent to all subscribers.

The process can use inotify interface if supported from the device, otherwise it can use the standard "access" function.

onvif_notify_server supports the following options but you should use them just for debugging purpose

Usage: onvif_notify_server [-p PID_FILE] [-q NUM] [-f] [-d LEVEL]

        -c CONF_FILE, --conf_file CONF_FILE
                path of the configuration file
        -p PID_FILE, --pid_file PID_FILE
                pid file
        -f, --foreground
                don't daemonize
        -d LEVEL, --debug LEVEL
                enable debug with LEVEL = 0..5 (default 0 = log fatal errors)
        -h, --help
                print this help
Option Description Default
conf_file the path of the file containing the configuration /etc/onvif_simple_server.conf
pid_file the path of the pid file if you want to change it /var/run/onvif_notify_server.pid
foreground don't fork -
debug debug level from 0 to 5 0

Compatibility

I tested this program with the following clients:

  • Onvif Device Manager (Windows)
  • Synology Surveillance Station (DSM 6.x and 7.x)
  • Onvifer (Android)

If you test it with other clients or NVR, please let me know opening a issue.

Below a list of the implemented functions, all other functions returns a generic soap fault.

Device

GetServices
GetServiceCapabilities
GetDevicermation
GetSystemDateAndTime
SystemReboot
GetScopes
GetUsers
GetWsdlUrl
GetCapabilities
GetNetworkInterfaces

Media

GetServiceCapabilities
GetVideoSources
GetVideoSourceConfigurations
GetVideoSourceConfiguration
GetCompatibleVideoSourceConfigurations
GetVideoSourceConfigurationOptions
GetProfiles
GetProfile
CreateProfile
GetVideoEncoderConfigurations
GetVideoEncoderConfiguration
GetCompatibleVideoEncoderConfigurations
GetVideoEncoderConfigurationOptions
GetGuaranteedNumberOfVideoEncoderInstances
GetSnapshotUri
GetStreamUri
GetAudioSources
GetAudioSourceConfigurations
GetAudioSourceConfiguration
GetAudioSourceConfigurationOptions
GetAudioEncoderConfigurations
GetAudioEncoderConfiguration
GetAudioEncoderConfigurationOptions
GetAudioDecoderConfigurations
GetAudioDecoderConfiguration
GetAudioDecoderConfigurationOptions
GetAudioOutputs
GetAudioOutputConfiguration
GetAudioOutputConfigurations
GetAudioOutputConfigurationOptions
GetCompatibleAudioSourceConfigurations
GetCompatibleAudioEncoderConfigurations
GetCompatibleAudioDecoderConfigurations
GetCompatibleAudioOutputConfigurations

PTZ

GetServiceCapabilities
GetConfigurations
GetConfiguration
GetConfigurationOptions
GetNodes
GetNode
GetPresets
GotoPreset
GotoHomePosition
ContinuousMove
RelativeMove
AbsoluteMove
Stop
GetStatus
SetPreset
SetHomePosition
RemovePreset

Events

GetServiceCapabilities
CreatePullPointSubscription
PullMessages
Subscribe
Renew
Unsubscribe
GetEventProperties
SetSynchronizationPoint

Credits

Thanks to:

License

GPLv3

DISCLAIMER

NOBODY BUT YOU IS RESPONSIBLE FOR ANY USE OR DAMAGE THIS SOFTWARE MAY CAUSE. THIS IS INTENDED FOR EDUCATIONAL PURPOSES ONLY. USE AT YOUR OWN RISK.

Donation

If you like this project, you can buy me a beer :)

Click here or use the below QR code to donate via PayPal