gsoap 生成 onvif 框架

gsoap 生成 onvif 框架 #

生成参数 #

wsdl2h #

-O4 #

aggressively optimizes the output by “schema slicing” to remove unused schema components, see our article Schema Slicing Methods to Reduce Development Costs of WSDL-Based Web Services for details;

-P #

don’t create polymorphic types inherited from xsd__anyType;

removes the base class xsd__anyType from the generated C++ classes, which are normally added by wsdl2h if the xsd:anyType XSD type is used somewhere in a WSDL.

However, for the ONVIF protocols we do not need to inherit the xsd__anyType class and we can reduce the generated code size accordingly;

-x #

don’t generate _XML any/anyAttribute extensibility elements;

removes the unnecessary generated code for the extensibility elements xsd:any and attributes xsd:anyAttribue, since we do not need to support these in general, except for some specific cases see further below. An alternative is to use option -d to generate embedded DOM code which allows you to add any XML content via the generated xsd__anyType __any members that are DOM nodes;

wsdl2h 其他参数:

  • -h : help
  • -s : don’t generate STL code (no std::string and no std::vector)
  • -t : typemapfile

soapcpp2 #

-2 #

forces SOAP 1.2, which is required by ONVIF;

-j #

For C++ projects you should generate C++ proxy classes using soapcpp2 option -j. Proxy classes are** easier to use** than the global functions that are generated without this option.

soapcpp2 其他参数:

  • -h: help
  • -x : don’t generate sample XML message files
  • -d : use path to save files
  • -p: save files with new prefix name instead of ‘soap’
  • -C: generate client-side source code only
  • -L: don’t generate soapClientLib/soapServerLib
  • -I : use path(s) for #import (paths separated with ‘:')

生成过程要做的事情 #

执行前 #

修改  typemap.dat

duration.h 毫秒级 (选了这个)

chrono_duration.h 纳秒级

To automatically enable the first choice of serializer for xsd:duration, add the following line to typemap.dat if not already there:

xsd__duration = #``import "custom/duration.h" | xsd__duration

This imports custom/duration.h into the wsdl2h-generated onvif.h binding interface.

执行 wsdl2h 后 #

change #import "wsdd10.h" to #import "wsdd5.h" in onvif.h

You may want to change #import "wsdd10.h" to #import "wsdd5.h" in onvif.h, because ONVIF uses WS-Addressing 2005/08 whereas WS-Discovery declared in wsdd10.h assumes WS-Addressing 2004/08

添加  #import “wsse.h”

执行 soapcpp2 后 #

Using WS-Security #

  • include

    • gsoap/plugin/wsseapi.h
  • compile

    • gsoap/plugin/wsseapi.c

    • gsoap/plugin/smdevp.c

    • gsoap/plugin/mecevp.c


  • link

    • -lgsoapssl++ 或 compilegsoap/stdsoap2.cppandgsoap/dom.cpp\


Using WS-Discovery #

When the ONVIF remotediscovery WSDL is used to build an ONVIF application, WS-Discovery is required.

  • include
    • gsoap/plugin/wsddapi.h
  • compile
    • gsoap/plugin/wsddapi.c

To support client-side WS-Discovery operations, we run soapcpp2 as follows as documented here:

soapcpp2 -a -x -L -pwsdd -I ~/gsoap-``2.8``/gsoap/``import ~/gsoap-``2.8``/gsoap/``import``/wsdd5.h

This generates wsddClient.cpp, which we will use later to compile with the project.

编译参数 #


CC = g++
CPPFLAG = -Wall -g -std=c++11 -w -fPIC -DWITH_NONAMESPACES -fno-use-cxa-atexit -fexceptions -DWITH_DOM  -DWITH_OPENSSL -DSOAP_DEBUG

INCLUDE += -I$(BASE_DIR) -I$(BASE_DIR)/onvif -I$(BASE_DIR)/gsoap -I/usr/local/opt/openssl@1.0/include
LIB = -lssl -lcrypto -L/usr/local/opt/openssl@1.0/lib
GsoapSOURCE = $(BASE_DIR)/gsoap
GsoapOBJ = $(GsoapSOURCE)/wsaapi.o $(GsoapSOURCE)/wsseapi.o $(GsoapSOURCE)/threads.o $(GsoapSOURCE)/duration.o \
          $(GsoapSOURCE)/smdevp.o $(GsoapSOURCE)/mecevp.o $(GsoapSOURCE)/dom.o $(GsoapSOURCE)/struct_timeval.o
OnvifSOURCE = $(BASE_DIR)/onvif
OnvifOBJ = $(OnvifSOURCE)/soapAdvancedSecurityServiceBindingProxy.o $(OnvifSOURCE)/soapDeviceBindingProxy.o $(OnvifSOURCE)/soapDeviceIOBindingProxy.o \
         $(OnvifSOURCE)/soapImagingBindingProxy.o $(OnvifSOURCE)/soapMediaBindingProxy.o $(OnvifSOURCE)/soapPTZBindingProxy.o \
         $(OnvifSOURCE)/soapPullPointSubscriptionBindingProxy.o $(OnvifSOURCE)/soapRemoteDiscoveryBindingProxy.o
SRC = $(GsoapSOURCE)/stdsoap2.o $(OnvifSOURCE)/soapC.o $(OnvifSOURCE)/wsddClient.o $(BASE_DIR)/main.o $(GsoapOBJ) $(OnvifOBJ)
OBJECTS = $(patsubst %.cpp,%.o,$(SRC))
TARGET = starry-eyes
all: $(TARGET)
    $(CC) $(CPPFLAG) $(OBJECTS)  $(INCLUDE)  $(LIB) -o $(TARGET)
$(OBJECTS):%.o : %.cpp
    $(CC) -c $(CPPFLAG) $(INCLUDE) $< -o $@
    rm -rf  $(OBJECTS)


Undefined symbols for architecture x86_64:
  "soap_s2xsd__dateTime(soap*, char const*, timeval*)", referenced from:
      soap_in_saml2__AuthnStatementType(soap*, char const*, saml2__AuthnStatementType*, char const*) in soapC.o
      soap_in_saml2__ConditionsType(soap*, char const*, saml2__ConditionsType*, char const*) in soapC.o
      soap_in_saml2__SubjectConfirmationDataType(soap*, char const*, saml2__SubjectConfirmationDataType*, char const*) in soapC.o
      soap_in_saml2__AssertionType(soap*, char const*, saml2__AssertionType*, char const*) in soapC.o
      soap_in_saml1__AuthenticationStatementType(soap*, char const*, saml1__AuthenticationStatementType*, char const*) in soapC.o
      soap_in_saml1__ConditionsType(soap*, char const*, saml1__ConditionsType*, char const*) in soapC.o
      soap_in_saml1__AssertionType(soap*, char const*, saml1__AssertionType*, char const*) in soapC.o

soap_s2xsd__dateTime 这个函数在框架生成的 soapC.cpp 中有多次调用,之前 onvif wsdl 生成的框架里是没有的。

后面找到是 gsoap 的 struct_timeval.c 中实现的,加入编译后,问题解决。


生成过程详情 #

1. 修改 typemap.dat,取消注释

xsdduration = #import “custom/duration.h” | xsdduration

2. 执行 wsdl2h 生成 onvif.h

wsdl2h -O4 -P -x -o onvif.h \ \ \ \ \ \ \ \

3. 修改 onvif.h,change #import "wsdd10.h" to #import "wsdd5.h

4. 修改 onvif.h,添加 #import “wsse.h”

5. 执行 soapcpp2 生成框架代码

6. 执行  soapcpp2 -pwsdd 生成  wsddClient.cpp

soapcpp2 -2 -C -j -x  -I ~/code/onvif/app-gsoap-2.8.98/gsoap:~/code/onvif/app-gsoap-2.8.98/gsoap/import:~/code/onvif/app-gsoap-2.8.98/gsoap/custom onvif.h -d onvif/

soapcpp2 -a -x -L -pwsdd -I ~/code/onvif/app-gsoap-2.8.98/gsoap/import ~/code/onvif/app-gsoap-2.8.98/gsoap/import/wsdd5.h -d onvif/