I’m not an English speaker, so I’m using a translator. Please understand.
NVR is being developed using C++. The Onvif protocol must be developed.
For related data research, we are looking at the official Onvif website, ChatGPT, and Gsoap official website and Github.
I have to implement all the search, communication, and control functions, but I have only implemented some of them, or I have difficulty referring to them because the environment is different.
So, I’m building Onvif myself, using WSDL. I’m building using Cmake and I’m having issues with enum and _ds__signature in wsseapi.h.
Is this the right direction I’m in, or should I look for another way?
My code is as follows.
main.cpp
#include "soapDeviceBindingProxy.h"
#include "soapH.h"
#include "wsseapi.h"
#include "wsddapi.h"
#include "soapStub.h"
#include "stdsoap2.h"
#include "namespaces.h"
#include <iostream>
#include <vector>
#include <string>
// ONVIF 장치 검색 함수
std::vector<std::string> discover_devices()
{
std::vector<std::string> devices;
struct soap *soap = soap_new();
soap_set_namespaces(soap, namespaces);
struct wsdd__ProbeType req;
struct __wsdd__ProbeMatches resp;
soap_default_wsdd__ProbeType(soap, &req);
req.Scopes = NULL; // Optional
req.Types = NULL; // Optional
if (soap_send___wsdd__Probe(soap, SOAP_MCAST_ADDR, NULL, &req) == SOAP_OK)
{
while (soap_recv___wsdd__ProbeMatches(soap, &resp) == SOAP_OK)
{
if (resp.wsdd__ProbeMatches->ProbeMatch != NULL)
{
for (int i = 0; i < resp.wsdd__ProbeMatches->__sizeProbeMatch; ++i)
{
devices.push_back(resp.wsdd__ProbeMatches->ProbeMatch[i].XAddrs);
}
}
}
}
soap_destroy(soap);
soap_end(soap);
soap_free(soap);
return devices;
}
int main(int argc, char *argv[])
{
std::vector<std::string> devices = discover_devices();
if (devices.empty())
{
std::cerr << "No ONVIF devices found!" << std::endl;
return 1;
}
std::cout << "Found ONVIF devices:" << std::endl;
for (const auto &device : devices)
{
std::cout << " - " << device << std::endl;
}
// 첫 번째 장치에 연결하여 정보 가져오기 connect
DeviceBindingProxy device;
device.soap_endpoint = devices[0].c_str();
_tds__GetCapabilities request;
_tds__GetCapabilitiesResponse response;
if (device.GetCapabilities(device.soap_endpoint, NULL, &request, response) == SOAP_OK)
{
std::cout << "GetCapabilities success!" << std::endl;
}
else
{
device.soap_stream_fault(std::cerr);
}
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(OnvifProject CXX)
set(CMAKE_CXX_STANDARD 17)
# GSOAP 라이브러리 경로 설정 (설치된 경로에 맞게 수정)
set(GSOAP_PATH /usr/share/gsoap)
# GSOAP 경로 포함
include_directories(${GSOAP_PATH}/import ${GSOAP_PATH}/plugin src)
link_directories(${GSOAP_PATH}/lib)
# GSOAP 생성된 파일을 포함
file(GLOB GSOAP_SOURCES "src/soapC.cpp" "src/soapClient.cpp" "src/soapServer.cpp" "src/stdsoap2.cpp")
file(GLOB SOURCES "src/*.cpp" "src/*.h" "src/*.nsmap")
# 실행 파일 생성
add_executable(OnvifProject ${SOURCES} ${GSOAP_SOURCES})
# GSOAP 라이브러리 링크
target_link_libraries(OnvifProject gsoapssl++ gsoap++)
gsoap 명령어
wsdl2h -o onvif.h wsdl/ver10/device/wsdl/devicemgmt.wsdl
soapcpp2 -C -i -L -I ${GSOAP_PATH}/import onvif.h