OServer C++ library
v3.0.0
Table of contents
- Overview
- Versions
- Library files
- OServer class description
- Json configuration string
- Callback mechanism
- Simple example
- Profile S template
- Test application
- Dependencies
- Build and connect to your project
Disclaimer
ONVIF® is a registered trademark of ONVIF, Inc. The ONVIF name is used here only in a descriptive manner to indicate that this library is intended to implement aspects of the ONVIF® specifications for interoperability. This project is not affiliated with, endorsed by, or sponsored by ONVIF, Inc. or its members. No ONVIF® conformance or certification is claimed. Any conformance claim can only be made by a finished product that has successfully completed ONVIF’s official conformance process and received a valid Declaration of Conformance (DoC) from ONVIF. No claim is made to the exclusive right to use “ONVIF” apart from the technical reference shown in this library’s documentation and code.
Overview
OServer is a C++ library that provides a server implementation based on the ONVIF® specifications. The library supports Linux only. It is designed for applications that require server functionality implementing the ONVIF® specifications, such as video surveillance systems, IP cameras, and other devices. The OServer library has the following dependencies: nlohmann JSON library (source code included), zlib (linked, ZLIB license), and openssl (linked, Apache 2.0 license). The repository also includes a template intended to help implement Profile S features. The Profile S template requires additional dependencies: VStreamerMediaMtx (provides an RTSP video server, source code included), CppHttpLib (provides an HTTP server required for ONVIF® Profile S, v3.14.0 source code included, MIT license), and ChildProcess (provides functions to run external processes). These dependencies provide video management and streaming capabilities used by the Profile S template. The library manages ONVIF® requests and responses using a callback mechanism. The user defines a global callback, and the library invokes this callback with request/response type parameters. Configuration of OServer is done via a JSON string. The OServer library requires the C++17 standard. Note: Claiming ONVIF® conformance for a product requires completion of ONVIF’s official conformance process and a valid DoC.
Versions
Table 1 - Library versions.
Version | Release date | What’s new |
---|---|---|
1.0.0 | 15.12.2024 | - First version. |
1.1.0 | 23.07.2025 | - Profile S support added. |
2.0.0 | 23.07.2025 | - Interface updated. </br> - Profile S template added. |
2.0.1 | 27.07.2025 | - VStreamerMediaMtx submodule update in example. |
2.0.2 | 10.08.2025 | - VStreamerMediaMtx submodule update in example. |
2.0.3 | 06.10.2025 | - VStreamerMediaMtx submodule update in example. |
3.0.0 | 10.10.2025 | - Class name changed to OServer. |
Library files
The library is supplied only by source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt --------------- Main CMake file of the library.
src -------------------------- Folder with library source code.
CMakeLists.txt ----------- CMake file of the library.
OServer.cpp -------------- C++ implementation file.
OServer.h ---------------- Main library header file.
OServerVersion.h --------- Header file with library version.
OServerVersion.h.in ------ CMake service file to generate version file.
nlohmann_json.hpp -------- Header file with nlohmann JSON library.
... ---------------------- Other backend files.
example ---------------------- Folder for example application files.
CMakeLists.txt ----------- CMake file of example application.
main.cpp ----------------- Source C++ file of example application.
DefaultConfigContent.h --- Header file with default configuration content.
profileSTemplate ------------- Folder for Profile S template files.
3rdparty ----------------- Folder with third-party libraries.
CMakeLists.txt ------- CMake file to include third-party libraries.
VStreamerMediaMtx ---- Folder with VStreamerMediaMtx source code.
CppHttpLib ----------- Folder with CppHttpLib source code.
ChildProcess --------- Folder with ChildProcess library source code.
images ------------------- Folder with images for snapshots.
CMakeLists.txt ----------- CMake file of Profile S template.
DefaultConfigContent.h --- Header file with default configuration content.
main.cpp ----------------- Source C++ file of Profile S template application.
OServer.json ------------- Example JSON configuration file.
OServerCallback.cpp ------ Source C++ file with ONVIF® server callback example.
Config.h ----------------- Header file with ONVIF® server configuration.
Ptz.cpp ------------------ Source C++ file with PTZ example.
Ptz.hpp ------------------ Header file with PTZ example.
utils.cpp ---------------- Source C++ file with utils functions.
utils.hpp ---------------- Header file with utils functions.
OServer class description
OServer class declaration
The OServer class is declared in the OServer.h file. Class declaration:
/// ONVIF® server class.
class OServer
{
public:
/// Type definition for the ONVIF® message handler callback function.
using onvif_handler_t = ONVIF_RET (*)(ONVIF_DEVICE *, ONVIF_MSG_TYPE, ...);
/// Get string of current library version.
static std::string getVersion();
/// Initialize the ONVIF® server with the JSON configuration string
/// and a global handler callback.
bool init(const std::string& jsonConfig, onvif_handler_t callback);
/// Initialize the ONVIF® server with the function pointers to initialize
/// the supported analytics rules and modules. This method is OPTIONAL.
void initAnalytics(void (*rulesInit)(onvif_SupportedRules *),
void (*modulesInit)(onvif_SupportedAnalyticsModules *));
/// Start the ONVIF® server.
bool start();
/// Stop the ONVIF® server.
bool stop();
/// Set the streaming capabilities of server device that ONVIF® server will use.
void setStreamingCapabilities(bool rtpMulticast, bool rtpRtspTcp);
};
getVersion method
The getVersion() method returns a string of the current class version. Method declaration:
static std::string getVersion();
Method can be used without OServer class instance:
cout << "OServer version: " << OServer::getVersion();
Console output:
OServer version: 3.0.0
init method
The init(…) method initializes the ONVIF® server. Method declaration:
bool init(const std::string& jsonConfig, onvif_handler_t callback);
Parameter | Value |
---|---|
jsonConfig | JSON string with configuration for the ONVIF® server. |
callback | Callback function to handle ONVIF® requests. See Callback mechanism for more details. |
Returns: TRUE if initialization is successful or FALSE if not.
initAnalytics method
The initAnalytics(…) method initializes ONVIF® analytics. Analytics functionality is not required by Profile S, it is an optional feature. It should be used for Profile M. Method declaration:
void initAnalytics(void (*rulesInit)(onvif_SupportedRules *),
void (*modulesInit)(onvif_SupportedAnalyticsModules *));
Parameter | Value |
---|---|
rulesInit | Function to initialize ONVIF® supported rules. |
modulesInit | Function to initialize ONVIF® supported analytics modules. |
start method
The start() method starts internal HTTP and WebSocket servers, runs different message parsers and processes. The method returns the result of the operation. Method declaration:
bool start();
Returns: TRUE if the server started successfully or FALSE if not.
stop method
The stop() method stops the operation of internal HTTP and WebSocket servers, different message parsers and processes, and frees used resources. Method declaration:
bool stop();
Returns: TRUE if the server stopped successfully or FALSE if not.
setStreamingCapabilities method
The setStreamingCapabilities(…) method sets the streaming capabilities of the ONVIF® server. Method declaration:
void setStreamingCapabilities(bool rtpMulticast, bool rtpRtspTcp);
Parameter | Value |
---|---|
rtpMulticast | Enable or disable RTP multicast streaming. |
rtpRtspTcp | Enable or disable RTP over RTSP over TCP streaming. |
JSON configuration string
The OServer library uses a JSON configuration string to initialize the server. The JSON string contains the configuration, including device information, supported services, and capabilities. The JSON string is passed to the init(…) method of the OServer class. By using a JSON configuration string, the user can define different configurations such as the number of cameras, their names, and other parameters. It is difficult to provide a complete template for the JSON configuration string because it depends on the specific use case and the features that are required. However, the profileSTemplate/OServer.json
file contains an example JSON configuration that can be used to initialize a server with two cameras and one PTZ controller. This configuration is intended to support Profile S features and does not, by itself, constitute an ONVIF® conformance claim.
Simple form of JSON configuration string is shown below:
{
"config": {
"log_enable": 1,
"log_level": 0,
"device": [
{
"server_ip": "",
"http_enable": 1,
"http_port": 10000,
"https_enable": 0,
"https_port": 1443,
"cert_file": "ssl.ca",
"key_file": "ssl.key",
"http_max_users": 16,
"need_auth": 0,
"EndpointReference": "urn:uuid:endpoint-1",
"information": {
"Manufacturer": "YourCompany",
"Model": "IPCamera",
"FirmwareVersion": "2.4",
"SerialNumber": "123456",
"HardwareId": "1.0"
},
"user": [
{
"username": "admin",
"password": "admin",
"userlevel": "Administrator"
},
{
"username": "user",
"password": "123456",
"userlevel": "User"
}
],
"RemoteUser": [
{
"username": "remote_user",
"password": "remote_password",
"UseDerivedPassword": false
}
],
"SystemDateTime": {
"TimeZone": {
"TZ": "UTC"
},
"DateTimeType": "NTP",
"DaylightSavings": false
},
"network": {
"NetworkProtocols": [
{
"Name": "HTTP",
"Enabled": true,
"Port": [80, 8080, 10000]
},
{
"Name": "HTTPS",
"Enabled": true,
"Port": [443, 8443]
},
{
"Name": "RTSP",
"Enabled": true,
"Port": [554, 8554]
}
],
"DNSInformation": {
"FromDHCP": false,
"SearchDomain": [
"example.com",
"example.org"
],
"DNSManual": [
{
"Type": "IPv4",
"IPv4Address": "10.10.10.4"
},
{
"Type": "IPv4",
"IPv4Address": "10.10.10.5"
},
{
"Type": "IPv4",
"IPv4Address": "10.10.10.6"
},
{
"Type": "IPv4",
"IPv4Address": "10.10.10.7"
}
]
},
"NTPInformation": {
"FromDHCP": false,
"NTPManual": [
{
"Type": "IPv4",
"IPv4Address": "192.168.1.1"
},
{
"Type": "IPv4",
"IPv4Address": "192.168.1.2"
},
{
"Type": "DNS",
"DNSname": "time.example.com"
},
{
"Type": "DNS",
"DNSname": "time.example.org"
}
]
},
"HostnameInformation": {
"FromDHCP": false,
"RebootNeeded": false
},
"NetworkGateway": {
"IPv4Address": [
"192.168.1.1",
"192.168.1.2"
]
},
"DiscoveryMode": "Discoverable",
"DynamicDNSInformation": {
"Type": "NoUpdate",
"Name": "example.com",
"TTL": 3600
},
"ZeroConfiguration": {
"InterfaceToken": "eth0",
"Enabled": true
}
},
"HashingAlgorithm": {
"@md5": 1,
"@sha256": 1
},
"VideoSources": [
{
"@token": "camera1",
"Framerate": 30.0,
"Resolution": {
"Width": 1920,
"Height": 1080
},
"VideoSourceModes": {
"@token": "camera1_VSMode1",
"@Enabled": true,
"MaxFramerate": 30.0,
"MaxResolution": {
"Width": 1920,
"Height": 1080
},
"Encodings": "H264",
"Reboot": false,
"Description": "Default Mode"
},
"ImagingSettings": {
"Brightness": 50.0,
"Focus": {
"AutoFocusMode": "AUTO",
"DefaultSpeed": 0.5,
"NearLimit": 0.0,
"FarLimit": 5.0,
"Smoothing": true
}
},
"ImagingOptions": {
"Brightness": {
"Min": 0.0,
"Max": 100.0
},
"Focus": {
"AutoFocusMode": [
"AUTO",
"MANUAL"
],
"DefaultSpeed": {
"Min": 0.0,
"Max": 1.0
},
"NearLimit": {
"Min": 0.0,
"Max": 5.0
},
"FarLimit": {
"Min": 0.0,
"Max": 5.0
}
}
},
"CurrentPresetToken": "imgPreset1",
"ThermalSupport": true,
"ThermalConfiguration": {
"ColorPalette": {
"@token": "palette1",
"@Type": "Rainbow",
"@Name": "RainbowPalette"
},
"Polarity": "WhiteHot",
"NUCTable": {
"@token": "nucTable1",
"@LowTemperture": -30.0,
"@HighTemperture": 50.0,
"@Name": "NUCTable1"
},
"Cooler": {
"Enabled": true,
"RunTime": 24.0
}
},
"RadiometryConfiguration": {
"RadiometryGlobalParameters": {
"ReflectedAmbientTemperature": 20.0,
"Emissivity": 0.95,
"DistanceToObject": 1.0,
"RelativeHumidity": 50.0,
"AtmosphericTemperature": 20.0,
"ExtOpticsTemperature": 20.0,
"ExtOpticsTransmittance": 0.95
}
}
}
],
"VideoSourceConfigurations": [
{
"@token": "camera1_config",
"Name": "camera1_config",
"SourceToken": "camera1",
"Bounds": {
"@width": 1920,
"@height": 1080,
"@x": 0,
"@y": 0
}
}
],
"VideoEncoderConfigurations": [
{
"@token": "camera1_video_encoder",
"@GovLength": 30,
"@AnchorFrameDistance": 1,
"@Profile": "High",
"@GuaranteedFrameRate": 30,
"Name": "camera1_video_encoder",
"Encoding": "H264",
"Resolution": {
"Width": 1920,
"Height": 1080
},
"RateControl": {
"@ConstantBitRate": true,
"FrameRateLimit": 30,
"BitrateLimit": 2048
},
"Multicast": {},
"Quality": 5,
"SessionTimeout": "PT10S",
"EncodingInterval": 1
}
],
"profile": [
{
"@token": "Camera1Stream1",
"fixed": true,
"Name": "Camera1Stream1",
"VideoSourceConfiguration": {
"@token": "camera1_config"
},
"VideoEncoderConfiguration": {
"@token": "camera1_video_encoder"
},
"stream_uri": {
"@append_params": 0,
"#text": ""
},
"PTZConfiguration": {
"@token": "ptz1"
},
"Presets": [
{
"@token": "preset1",
"Name": "MainPosition",
"PTZPosition": {
"PanTilt": {
"@x": 3,
"@y": 3
},
"Zoom": {
"@x": 1
}
}
},
{
"@token": "preset2",
"Name": "SecondPosition",
"PTZPosition": {
"PanTilt": {
"@x": 5,
"@y": 5
},
"Zoom": {
"@x": 2
}
}
}
],
"PresetTours": [
{
"@token": "tour1",
"Name": "Tour1",
"Status": {
"State": "Idle"
},
"AutoStart": true,
"StartingCondition": {
"@RandomPresetOrder": false,
"RecurringTime": "60",
"RecurringDuration": "PT1M30S",
"Direction": "Forward"
},
"TourSpot": [
{
"PresetDetail": {
"PresetToken": "preset1",
"Home": true,
"PTZPosition": {
"PanTilt": {
"@x": 0,
"@y": 0
},
"Zoom": {
"@x": 0
}
}
},
"Speed": {
"PanTilt": {
"@x": 0.5,
"@y": 0.5
},
"Zoom": {
"@x": 1
}
},
"StayTime": "PT2S"
}
]
}
]
}
],
"PTZNodes": [
{
"@token": "ptzNode1",
"@FixedHomePosition": true,
"@GeoMove": true,
"Name": "PTZNode1",
"SupportedPTZSpaces": {
"AbsolutePanTiltPositionSpace": {
"XRange": {
"Min": -5.0,
"Max": 6.0
},
"YRange": {
"Min": -9.0,
"Max": 10.0
}
},
"AbsoluteZoomPositionSpace": {
"XRange": {
"Min": 0.0,
"Max": 3.0
}
},
"ContinuousPanTiltVelocitySpace": {
"XRange": {
"Min": -20.0,
"Max": 20.0
},
"YRange": {
"Min": -30.0,
"Max": 30.0
}
},
"ContinuousZoomVelocitySpace": {
"XRange": {
"Min": -15.0,
"Max": 15.0
}
},
"PanTiltSpeedSpace": {
"XRange": {
"Min": 0.0,
"Max": 4.0
}
},
"ZoomSpeedSpace": {
"XRange": {
"Min": 0.0,
"Max": 7.0
}
}
},
"MaximumNumberOfPresets": 100,
"HomeSupported": true,
"Extension": {
"SupportedPresetTour": {
"MaximumNumberOfPresetTours": 10,
"PTZPresetTourOperation": [
"Start",
"Stop",
"Pause",
"Extended"
]
}
},
"AuxiliaryCommands": [
"Wiper start",
"Wiper stop"
]
}
],
"PTZConfigurations": [
{
"@token": "ptz1",
"@MoveRamp": 1,
"@PresetRamp": 2,
"@PresetTourRamp": 3,
"Name": "PTZCfg1",
"NodeToken": "ptzNode1",
"UseCount": 0,
"DefaultPTZSpeed": {
"PanTilt": {
"@x": 0.5,
"@y": 0.5
},
"Zoom": {
"@x": 0.5
}
},
"DefaultPTZTimeout": "PT5S",
"PanTiltLimits": {
"Range": {
"XRange": {
"Min": -13,
"Max": 13
},
"YRange": {
"Min": -14,
"Max": 14
}
}
},
"ZoomLimits": {
"Range": {
"XRange": {
"Min": -9,
"Max": 9
}
}
},
"Extension": {
"PTControlDirection": {
"EFlip": {
"Mode": "ON"
},
"Reverse": {
"Mode": "AUTO"
}
}
}
}
],
"replay_session_timeout": 60,
"scope": [
"onvif://www.onvif.org/location/country/PL",
"onvif://www.onvif.org/type/video_encoder",
"onvif://www.onvif.org/name/IP-Camera",
"onvif://www.onvif.org/hardware/YourHardwareId"
],
"event": {
"renew_interval": 60,
"simulate_enable": 1
}
}
]
}
}
The provided JSON string configures the ONVIF® server with a single camera, single stream, and one PTZ controller. This configuration can be used as a base template to create your ONVIF® configuration with different cameras and streams.
In order to add a new camera, the following steps should be performed:
- Add a new entry to the
VideoSources
array with the camera token, resolution, framerate, and imaging settings. - Add a new entry to the
VideoSourceConfigurations
array with the camera token and bounds. - Add a new entry to the
VideoEncoderConfigurations
array with the camera token, encoding settings, and resolution. - Add a new entry to the
profile
array with the camera token, video source configuration, and video encoder configuration.
Callback mechanism
The OServer class provides a callback mechanism to handle ONVIF® requests. The callback function should match the following signature:
ONVIF_RET onvif_global_handler(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...);
The callback function will be called for each ONVIF® request received by the server. The msg_type
parameter indicates the type of the request, and the variable arguments can be used to pass additional data related to the request.
// Example callback function
ONVIF_RET onvif_cb(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...)
{
va_list args;
va_start(args, msg_type);
// Handle the ONVIF® request based on the msg_type
switch (msg_type)
{
case GetImagingSettings:
// Handle GetImagingSettings request
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_GetImagingSettings_REQ *);
// Use vsl and req to get the imaging settings for the requested video source
break;
case SetImagingSettings:
// Handle SetImagingSettings request
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_SetImagingSettings_REQ *);
// Use vsl and req to set the imaging settings for the requested video source
break;
// Add more cases for other message types
}
va_end(args);
return ONVIF_OK;
}
For the requests that require additional parameters (which can be information about the request or response), the callback function can use va_arg
to retrieve the parameters from the variable argument list. The parameters are defined in the ONVIF® specification for each message type. For example, for the SetImagingSettings
message type, the parameters can include a pointer to the VideoSourceList
and a pointer to the img_SetImagingSettings_REQ
structure.
case SetImagingSettings:
{
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_SetImagingSettings_REQ *);
}
The req parameter will contain the request data that the ONVIF® client sent, so you can use it to apply settings to your camera. For example:
yourCameraBrightness = req->ImagingSettings.Brightness;
yourCameraContrast = req->ImagingSettings.Contrast;
yourCameraColorSaturation = req->ImagingSettings.ColorSaturation;
The requests that require a response instead of an action also work the same way. For example, for the GetImagingSettings
message type, the parameters can include a pointer to the VideoSourceList
and a pointer to the img_GetImagingSettings_REQ
structure. The response can be set by modifying the ImagingSettings
field of the VideoSourceList
.
case GetImagingSettings:
{
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_GetImagingSettings_REQ *);
}
This time the req parameter will contain data related to the request, for example the camera token. You can use this token to determine which camera the ONVIF® client requested settings for. After that, you can set response data to vsl->ImagingSettings. For example:
vsl->ImagingSettings.Brightness = 25.0f; // Example value, replace with actual camera settings.
vsl->ImagingSettings.Contrast = 50.0f; // Example value, replace with actual camera settings.
vsl->ImagingSettings.ColorSaturation = 75.0f; // Example value, replace with actual camera settings.
The callback function should return an ONVIF_RET
value indicating the result of the operation. The possible return values are defined in the ONVIF® specification and include ONVIF_OK
, ONVIF_ERR_InvalidToken
, and other error codes. Please refer to the file /src/OnvifMessageTypes.h
for the full list of message types, their parameters, and return values.
The /profileSTemplate/ServerCallback.cpp file contains an example of the callback function that handles ONVIF® requests to provide Profile S support. Please note that Profile S compliance requires additional features such as real video streaming, PTZ control, HTTP server for system restore, and RTSP over HTTP tunneling. These features are implemented in the Profile S template application and are not part of the OServer library functionality. The callback function in the Profile S template handles ONVIF® requests related to video streaming, PTZ control, and other Profile S-specific features.
Simple example
The application below shows the simplest usage of OServer. The application creates an OServer object and initializes it with a simple callback.
#include <iostream>
#include <string>
#include <thread>
#include <chrono>
#include "OnvifImage.h"
#include "OServer.h"
#include "OnvifGlobalHandler.h"
#include "DefaultConfigContent.h"
/// ONVIF® callback function. This function handles ONVIF® messages.
ONVIF_RET onvifCallback(ONVIF_DEVICE *p_device, ONVIF_MSG_TYPE msg_type, ...)
{
va_list args;
va_start(args, msg_type);
// Unless the request is explicitly rejected, it's better to return ONVIF_OK
// for many requests for test tool compatibility.
ONVIF_RET ret = ONVIF_OK;
// Check the message type and handle it accordingly.
switch (msg_type)
{
// Handle SetImagingSettings request.
case SetImagingSettings:
{
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_SetImagingSettings_REQ *);
// Get token. Camera token is defined in config file.
std::string cameraName(vsl->VideoSource.token);
// Some logic depends on camera name if we have multiple cameras.
// Apply these settings to your camera.
// Example: yourCamera.setBrightness(req->ImagingSettings.Brightness);
// Example: yourCamera.setContrast(req->ImagingSettings.Contrast);
// Example: yourCamera.setColorSaturation(req->ImagingSettings.ColorSaturation);
break;
}
// Handle GetImagingSettings request.
case GetImagingSettings:
{
auto vsl = va_arg(args, VideoSourceList *);
auto req = va_arg(args, img_GetImagingSettings_REQ *);
// Get token. Camera token is defined in config file.
std::string cameraName(vsl->VideoSource.token);
// Some logic depends on camera name if we have multiple cameras.
// Fill image settings.
auto imageSettings = &vsl->ImagingSettings;
imageSettings->Brightness = 25.0f; // Example value.
imageSettings->Contrast = 50.0f; // Example value.
imageSettings->ColorSaturation = 75.0f; // Example value.
break;
}
// ... Other cases for handling different ONVIF® messages ...
}
va_end(args);
// Return the result of the operation.
return ret;
}
/// Entry point.
int main(int argc, char **argv)
{
// Create ONVIF® server object.
cr::onvif::OServer oServer;
// Initialize ONVIF® server with the JSON configuration and callback function.
if (!oServer.init(g_defaultConfigContent, onvifCallback))
return -1;
// Start ONVIF® server.
if (!oServer.start())
return -1;
// Wait key press to stop the server.
std::cout << "ONVIF® server started. Press Enter to stop..." << std::endl;
std::cin.get();
oServer.stop();
return 0;
}
Profile S template
The OServer library provides a template for Profile S. The template is located in the profileSTemplate folder. The Profile S template requires additional dependencies: VStreamerMediaMtx (provides an RTSP video server, source code included), CppHttpLib (provides an HTTP server required for ONVIF® Profile S, v3.14.0 source code included, MIT license), and ChildProcess (provides functions to run external processes). These dependencies provide video management and streaming capabilities used by the Profile S template. Use of this template does not, by itself, imply ONVIF® conformance.
The most important files in the profileSTemplate folder are:
- ServerCallback.cpp - file with ONVIF® server callback example. This file contains the implementation of the callback function that handles ONVIF® requests.
- ServerProfileS.json - example JSON configuration file for the ONVIF® server. This file contains the configuration for the ONVIF® server, including device information, supported services, and capabilities.
In order to support Profile S, the OServer library uses the VStreamerMediaMtx (source code included) library, which uses the MediaMTX executable to provide RTSP streaming. The mediamtx executable and mediamtx.yml configuration file should be located in the same folder as the OServer executable. The mediamtx application can be obtained from MediaMTX releases. Follow the instructions from MediaMTX.
The OServer library also uses the CppHttpLib library to provide HTTP server functionality for the system restore feature of Profile S. The source code of the CppHttpLib library is located in the 3rdparty/CppHttpLib folder. The CppHttpLib library is used to handle HTTP requests and responses, and to provide the necessary functionality for Profile S-related features.
Lastly, Profile S requires RTSP over HTTP tunneling support. However, the VStreamerMediaMtx library does not support RTSP over HTTP tunneling. Therefore, the OServer library uses the live555ProxyServer executable to provide RTSP over HTTP tunneling support. The live555ProxyServer executable should be located in the same folder as the OServer executable.
Instructions to build live555ProxyServer:
- Obtain live555 library source code
git clone https://github.com/rgaufman/live555 cd live555
-
Modify config file for C++ std support. So open related config file for example, config.linux-64bit. Add
-DNO_STD_LIB
to CPLUSPLUS_FLAGS. - Build live555 library
./genMakefiles linux-64bit make
- live555ProxyServer executable is located in the live555/proxyServer folder. Copy live555ProxyServer executable to the same folder as the OServer executable.
Test application
The OServer library provides a test application located in the test folder. The test application demonstrates the usage of the OServer library and provides examples of how to use the library’s features. The test application includes all features of the OServer library but does not provide any RTSP streams.
In order to run the test application, the /test/onvif.json file should be located in the same folder as the test application executable. This file contains the configuration for the ONVIF® server, including device information, supported services, and capabilities.
Dependencies
The OServer library has dependencies on openssl and zlib. To install these dependencies using a package manager, you can use the following commands:
sudo apt install libssl-dev zlib1g-dev
Build and connect to your project
Typical commands to build OServer library:
cd OServer
mkdir build
cd build
cmake ..
make
If you want to connect the OServer library to your CMake project as source code, you can follow these steps. For example, if your repository has this structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create a 3rdparty folder in your repository and place the OServer repository folder there. The new structure of your repository will be:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
3rdparty
OServer
Create a `CMakeLists.txt` file in the **3rdparty** folder. The `CMakeLists.txt` should contain:
```cmake
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_OSERVER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_OSERVER)
SET(${PARENT}_OSERVER ON CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_OSERVER)
add_subdirectory(OServer)
endif()
The OServer default configuration supports Profile S mandatory and optional features. For enabling/disabling other features, the following flags can be used in the CMakeLists.txt file:
# Default configuration supports Profile S.
SET(ONVIF_HTTPD_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MEDIA_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_IMAGE_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_DEVICE_IO_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MEDIA2_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PTZ_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_IP_FILTER_SUPPORT ON CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_MPEG4_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROFILE_G_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROFILE_C_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_CREDENTIAL_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_ACCESS_RULES_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_SCHEDULE_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_AUDIO_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_VIDEO_ANALYTICS_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_THERMAL_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_RECEIVER_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_STORAGE_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_PROVISIONING_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_GEOLOCATION_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
SET(ONVIF_DOT11_SUPPORT OFF CACHE BOOL "" ${REWRITE_FORCE})
The 3rdparty/CMakeLists.txt file adds the OServer folder to your project and excludes the test application and examples from compilation (by default, the test application and examples are excluded from compilation if OServer is included as a sub-repository). Your repository’s new structure will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
OServer
Next, you need to include the 3rdparty folder in the main CMakeLists.txt file of your repository. Add the following line at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next, you have to include the OServer library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} OServer)
Done!