ONVIF device server - Basic ONVIF server implementation

From RidgeRun Developer Wiki





Previous: Dependencies Index Next: Getting Started






The library is easy to use, you just need to instantiate the server attributes and implement some class interfaces, to know what classes you need to implement, please refer to the section Important classes. For the basic server, you have to set some attributes:

Attribute Use
Minimum password lenght Sets the default minimum password lenght
Server manufacturer Sets the server manufacturer data for the requests
Server model Sets the server model data for the requests.
Firmware version Sets the firmware version data for requests
Serial number Sets the serial number data for the request
Server hardware ID Sets the server hardware ID data for the request
Server port Sets the port that the server is going to use
Discovery endpoint Sets the endpoint for the discovery functionality
Discovery types Sets the discovery types for the discovery functionality
Discovery scopes Sets the discovery scopes for the discovery functionality
Discovery version Sets the discovery version of the discovery functionality

The server class also has some methods to set the data, these methods will be explained here:

Method Functionality
OnvifServer(interface,port,media,fileEncryption) This is the constructor of the class, it receives which network interface is going to use, the port for the server, the media handler,aka,the implementation of the interface and a file encryptor which is the implementation of the class X.
setAutosave Sets the autosave functionality, allowing the server to save the configurations after one is changed, this functionality uses the file encryptor set by the constructor.
defineRtspPorts(min,max) Defines an interval of ports that the server is going to assign to the multimedia profiles.
setNetworkHandler(netHandler) Sets the network handler that the server uses, this class need to be an implementation of INetwork
loadConfiguration Reads the multimedia configurations from a Json file written by the encryptor that the server uses.
getDeviceCapabilities This method is used to access the device capabilities classes, these classes hold the available functionalities values, meaning, their values, and if they are enabled.
getMediaServiceCapabilities This method is used to access the media capabilities class, this class hold the values for the media capabilities used in the requests.
setSystemHandler Sets the system handler for the server, this class is used to reboot the system and get the date and time values.
addStream(stream,fixed) Adds a stream to the server, this creates a multimedia profile. This creates normally the default media configurations. The fixed argument is used to set that the stream cannot be deleted nor modified.
setFirmwareVersion Sets the firmware version of the server
setSerialNumber Sets the firmware version of the server
setHardwareID Sets the firmware version of the server
setMaximumEncoders Sets the maximum quantity of each encoder.
initDiscovery Instantiates the discovery in the server
setDiscoveryEndpoint Sets the discovery endpoint of the discovery functionality
setDiscoveryTypes Sets the discovery types of the discovery functionality
setDiscoveryScopes Sets the discovery scope of the discovery functionality
setDiscoveryMetaVersion Sets the discovery meta version of the discovery functionality
start Starts the server.

In the end the implementation class should look something like the next one:

/**
 * Copyright (C) 2021 RidgeRun, LLC (http://www.ridgerun.com)
 * All Rights Reserved.
 *
 * The contents of this software are proprietary and confidential to RidgeRun,
 * LLC.  No part of this program may be photocopied, reproduced or translated
 * into another programming language without prior written consent of
 * RidgeRun, LLC.  The user is free to modify the source code after obtaining
 * a software license from RidgeRun.  All source code changes must be provided
 * back to RidgeRun without any encumbrance.
 */

#include <signal.h>
#include <unistd.h>

#include <iostream>

#include <CaesarCypherEncryptor.h>
#include <common/DataTypes.h>
#include <DeviceCapabilities.h>
#include <GSTDMediaClient.h>
#include <JPEGEncoder.h>
#include <LinuxSystem.h>
#include <MediaServiceCapabilities.h>
#include <SystemdNetwork.h>

#define NET_INTERFACE "eth0"
#define DEFAULT_SOURCE_NAME1 "source1"
#define DEFAULT_SOURCE_WIDTH 640
#define DEFAULT_SOURCE_HEIGHT 480
#define DEFAULT_SOURCE_FPS 30
#define DEFAULT_ENCODER_WIDTH 640
#define DEFAULT_ENCODER_HEIGHT 480
#define DEFAULT_ENCODER_FPS 30

#define DEFAULT_MINIMUM_PASSWORD_SIZE 8
#define DEFAULT_STREAM_MAPPING1 "stream1"
#define DEFAULT_STREAM_PORT "8000"
#define DEFAULT_SERVER_MANUFACTURER "MyManufacturer"
#define DEFAULT_SERVER_MODEL "MyModel"
#define DEFAULT_SERVER_FIRMWARE_VERSION "MyFirmwareVersion"
#define DEFAULT_SERVER_SERIAL_NUMBER "MySerialNumber"
#define DEFAULT_SERVER_HARDWARE_ID "MyHardwareID"
#define DEFAULT_SERVER_PORT 8080
#define DEFAULT_MAX_USERS 10
#define DEFAULT_MAX_USERS_NAME_LENGTH 20
#define DEFAULT_MAX_PASSWORD_LENGHT 20
#define DEFAULT_NET_CONFIGURATION_FILE "/lib/systemd/network/80-container-vz.network"
#define DEFAULT_MAX_ENCODERS 8
#define DEFAULT_MAX_H264_ENCODERS 2
#define DEFAULT_MAX_H265_ENCODERS 2
#define DEFAULT_MAX_JPEG_ENCODERS 2
#define DEFAULT_MAX_MPEG4_ENCODERS 2
#define DEFAULT_MAX_NUMBER_PROFILES 10
/*Discovery Configs*/
#define DISCOVERY_ENDPOINT "urn:endpoint"
#define DISCOVERY_TYPES "\"http://www.onvif.org/ver10/network/wsdl\":NetworkVideoTransmitter"
#define DISCOVERY_SCOPES "onvif://www.onvif.org/name/Unknown onvif://www.onvif.org/Profile/Streaming"
#define DISCOVERY_VERSION 0

CaesarCypherEncryptor *fileEncryption = new CaesarCypherEncryptor();
GSTDMediaClient *media = new GSTDMediaClient("127.0.0.1", 5000, -1, 1);
void signal_callback_handler(int signum);

OnvifServer *Server = new OnvifServer(NET_INTERFACE, DEFAULT_SERVER_PORT, media,
                                     fileEncryption);
    
bool leave;

void signal_callback_handler(int signum) {
  Server->stop();
  leave = true;
  std::cout << "Stopping server... " << std::endl;
  std::cout << "Stopped server... " << std::endl;
  std::cout << "... " << std::endl;
  exit(signum);
}

int main() {
  Server->setAutosave(false);
  Server->defineRtspPorts(8081,8091);

  std::map<std::string, std::string> net_files = {
      {NET_INTERFACE, DEFAULT_NET_CONFIGURATION_FILE}};
  SystemdNetwork *net = new SystemdNetwork(net_files);
  Server->setNetworkHandler(net);

  Server->loadConfiguration();
  Server->setAutosave(true);

  std::shared_ptr<DeviceCapabilities> deviceCapabilities = Server->getDeviceCapabilities();
  
  std::shared_ptr<DeviceSecurityCapabilities>  deviceSecurityCapabilities = deviceCapabilities->getSecurity();
  deviceSecurityCapabilities->setMaxPasswordLength(DEFAULT_MAX_PASSWORD_LENGHT);
  deviceSecurityCapabilities->setMaxUsers(DEFAULT_MAX_USERS);
  deviceSecurityCapabilities->setMaxUsersNameLenght(DEFAULT_MAX_USERS_NAME_LENGTH);
  deviceSecurityCapabilities->setUsernameToken(true);
  deviceSecurityCapabilities->setMinPasswordLength(DEFAULT_MINIMUM_PASSWORD_SIZE);

  std::shared_ptr<DeviceSystemCapabilities> deviceSystemCapabilities = deviceCapabilities->getSystem();
  deviceSystemCapabilities->setDiscoveryResolve(true);
  deviceSystemCapabilities->setRemoteDiscovery(true);
  
  std::shared_ptr<MediaServiceCapabilities> mediaServiceCapabilities = Server->getMediaServiceCapabilities();
  mediaServiceCapabilities->setMaximumNumberOfProfiles(DEFAULT_MAX_NUMBER_PROFILES);

  VideoSource videoSource1;
  videoSource1.setName(DEFAULT_SOURCE_NAME1);
  videoSource1.setFramerate(DEFAULT_SOURCE_FPS);
  videoSource1.setWidth(DEFAULT_SOURCE_WIDTH);
  videoSource1.setHeight(DEFAULT_SOURCE_HEIGHT);

  JPEGEncoder videoEncoder1;
  StreamData stream;
  
  videoEncoder1.setWidth(DEFAULT_ENCODER_WIDTH);
  videoEncoder1.setHeight(DEFAULT_ENCODER_HEIGHT);
  videoEncoder1.setFrameRate(DEFAULT_ENCODER_FPS);

  stream.setVideoSource(videoSource1);
  stream.setVideoEncoder(videoEncoder1);
  stream.setSourceMapping(DEFAULT_STREAM_MAPPING1);
  stream.setPort(DEFAULT_STREAM_PORT);

  LinuxSystem * system_management = new LinuxSystem();
  Server->setSystemHandler(system_management);
  Server->addStream(stream, true);
  Server->setFirmwareVersion(DEFAULT_SERVER_FIRMWARE_VERSION);
  Server->setSerialNumber(DEFAULT_SERVER_SERIAL_NUMBER);
  Server->setHardwareID(DEFAULT_SERVER_HARDWARE_ID);
  Server->setMaximumEncoders(DEFAULT_MAX_ENCODERS, DEFAULT_MAX_H264_ENCODERS,
                             DEFAULT_MAX_H265_ENCODERS, DEFAULT_MAX_JPEG_ENCODERS,
                             DEFAULT_MAX_MPEG4_ENCODERS);

  Server->initDiscovery();
  Server->setDiscoveryEndpoint(DISCOVERY_ENDPOINT);
  Server->setDiscoveryTypes(DISCOVERY_TYPES);
  Server->setDiscoveryScopes(DISCOVERY_SCOPES);
  Server->setDiscoveryMetaVersion(DISCOVERY_VERSION);
  
  std::cout << "Starting server... " << std::endl;
  Server->start();
  std::cout << "Server started... " << std::endl;

  leave = false;
  signal(SIGINT, signal_callback_handler);
  while (!leave)
    sleep(1);

  std::cout << "Server stopped... " << std::endl;

  return EXIT_SUCCESS;
}


Previous: Dependencies Index Next: Getting Started