gsoap实现onvif

参见文章《gsoap2.8.11实现onvif_discover详细教程》和文章(重点看),还有文章

1.下载gsoap

2.去onvif相关页面,将对应的wsdl文件下载下来,也可以去页面,查找ONVIF WSDL and XML Schemas Specifications得到,提供一个下载onvif的wsdl下载文件

3.打开所有的wsdl,查找对应的schemaLocation="http://xxx/xxx.xsd",下载对应的xsd文件

4.查找所有wsdl和xsd,查找location="http://xxx/xxx.wsdl",下载对应的wsdl

5.修改所有的wsdl和xsd,将上述schemaLocation和location等号后面的内容中关于路径部分的全去掉,因为对应文件已经下载到本地了,比如schemaLocation=“http://docs.oasis-open.org/wsn/b-2.xsd"改为schemaLocation=“b-2.xsd"

6.修改typemap.dat文件

参见文档的“How do I use gSOAP for the ONVIF specifications?”

#	ONVIF recommended prefixes
tds	= "http://www.onvif.org/ver10/device/wsdl"
tev	= "http://www.onvif.org/ver10/events/wsdl"
tls	= "http://www.onvif.org/ver10/display/wsdl"
tmd	= "http://www.onvif.org/ver10/deviceio/wsdl"
timg	= "http://www.onvif.org/ver20/imaging/wsdl"
trt	= "http://www.onvif.org/ver10/media/wsdl"
tptz	= "http://www.onvif.org/ver20/ptz/wsdl"
trv	= "http://www.onvif.org/ver10/receiver/wsdl"
trc	= "http://www.onvif.org/ver10/recording/wsdl"
tse	= "http://www.onvif.org/ver10/search/wsdl"
trp	= "http://www.onvif.org/ver10/replay/wsdl"
tan	= "http://www.onvif.org/ver20/analytics/wsdl"
tad	= "http://www.onvif.org/ver10/analyticsdevice/wsdl"
tdn	= "http://www.onvif.org/ver10/network/wsdl"
tt	= "http://www.onvif.org/ver10/schema"
#	OASIS recommended prefixes
wsnt	= "http://docs.oasis-open.org/wsn/b-2"
wsntw	= "http://docs.oasis-open.org/wsn/bw-2"
wsrfbf	= "http://docs.oasis-open.org/wsrf/bf-2"
wsrfr	= "http://docs.oasis-open.org/wsrf/r-2"
wsrfrw  = "http://docs.oasis-open.org/wsrf/rw-2"
wstop	= "http://docs.oasis-open.org/wsn/t-1"
#	WS-Discovery 1.0 remapping
wsdd10__HelloType		= | wsdd__HelloType
wsdd10__ByeType			= | wsdd__ByeType
wsdd10__ProbeType		= | wsdd__ProbeType
wsdd10__ProbeMatchesType	= | wsdd__ProbeMatchesType
wsdd10__ProbeMatchType		= | wsdd__ProbeMatchType
wsdd10__ResolveType		= | wsdd__ResolveType
wsdd10__ResolveMatchesType	= | wsdd__ResolveMatchesType
wsdd10__ResolveMatchType	= | wsdd__ResolveMatchType
#	SOAP-ENV mapping
SOAP_ENV__Envelope	= struct SOAP_ENV__Envelope { struct SOAP_ENV__Header *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope
SOAP_ENV__Header	= | struct SOAP_ENV__Header
SOAP_ENV__Fault		= | struct SOAP_ENV__Fault
SOAP_ENV__Detail	= | struct SOAP_ENV__Detail
SOAP_ENV__Code		= | struct SOAP_ENV__Code
SOAP_ENV__Subcode	= | struct SOAP_ENV__Subcode
SOAP_ENV__Reason	= | struct SOAP_ENV__Reason

7.修改gsoap目录下的wsa5.h,将如下内容注释掉

// Added
//gsoap SOAP_ENV service method-action: Fault http://www.w3.org/2005/08/addressing/soap/fault
int SOAP_ENV__Fault
(       _QName			 faultcode,		// SOAP 1.1
        char			*faultstring,		// SOAP 1.1
        char			*faultactor,		// SOAP 1.1
        struct SOAP_ENV__Detail	*detail,		// SOAP 1.1
        struct SOAP_ENV__Code	*SOAP_ENV__Code,	// SOAP 1.2
        struct SOAP_ENV__Reason	*SOAP_ENV__Reason,	// SOAP 1.2
        char			*SOAP_ENV__Node,	// SOAP 1.2
        char			*SOAP_ENV__Role,	// SOAP 1.2
        struct SOAP_ENV__Detail	*SOAP_ENV__Detail,	// SOAP 1.2
	void
);

8.生成onvif.h,可以建立如下bat脚本文件执行
@echo off
set GSoapPath=E:\Source\c++\gsoap-2.8
Set GSoapSPath=%GSoapPath%\gsoap
set GSoapBinPath=%GSoapSPath%\bin\win32
set TypeMapFile=%GSoapBinPath%\typemap.dat
set OnVifHFile=onvif.h
set DestSourcePath=.\
echo "generate %OnVifHFile%"
if exist "%OnVifHFile%" del "%OnVifHFile%"
%GSoapBinPath%\wsdl2h.exe -sck -t %TypeMapFile% -o %OnVifHFile% analytics.wsdl analyticsdevice.wsdl deviceio.wsdl devicemgmt.wsdl display.wsdl event.wsdl imaging.wsdl media.wsdl ptz.wsdl Receiver.wsdl Recording.wsdl remotediscovery.wsdl Replay.wsdl Search.wsdl
if not exist "%OnVifHFile%" goto 2
echo "generate %OnVifHFile% success"
:2


当然也可以直接通过访问网上的wsdl完成

%GSoapBinPath%\wsdl2h.exe -sck -t %TypeMapFile% -o %OnVifHFile% http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl ...


9.修改生成的onvif.h,增加一句#import "wsse.h",用于身份验证


10.运行soapcpp2,生成代码,可以建立如下bat脚本运行

@echo off
set GSoapPath=E:\Source\c++\gsoap-2.8
Set GSoapSPath=%GSoapPath%\gsoap
set GSoapBinPath=%GSoapSPath%\bin\win32
set OnVifHFile=onvif.h
set DestSourcePath=.\
if not exist "%OnVifHFile%" goto 1
echo "generate Onvif source code" 
%GSoapBinPath%\soapcpp2.exe -2 -L -c -x -d%DestSourcePath% -I%GSoapSPath%\import;%GSoapSPath%\custom;%GSoapSPath% %OnVifHFile%
echo "generate Onvif source code end" 
goto 2
:1
echo "%OnVifHFile% not exist" 
:2


11.8-10步可以用如下bat脚本完成

@echo off
set GSoapPath=E:\Source\c++\gsoap-2.8
Set GSoapSPath=%GSoapPath%\gsoap
set GSoapBinPath=%GSoapSPath%\bin\win32
set TypeMapFile=%GSoapBinPath%\typemap.dat
set OnVifHFile=onvif.h
set OnVifHTempFile=onviftmp.h
set DestSourcePath=..\onvifserver
set AllWSDLFiles=actionengine.wsdl analytics.wsdl analyticsdevice.wsdl deviceio.wsdl devicemgmt.wsdl display.wsdl event.wsdl imaging.wsdl media.wsdl ptz.wsdl Receiver.wsdl Recording.wsdl remotediscovery.wsdl Replay.wsdl Search.wsdl
set WSDLFiles=%AllWSDLFiles%
set WSDLCFlag=-s -c -k
set WSDLCPPFlag=-s -k
set SOAPCFlag=-L -x -S -2 -c
set SOAPCPPFlag=-L -x -S -2 
if "%1"=="-h" goto help
if "%1"=="-l" (
  if "%2"=="cpp" (
    set MFlag=2
  ) else (
    set MFlag=1
  )
)

echo "delete files"
if exist "%OnVifHFile%" del "%OnVifHFile%"
del *.nsmap
del %DestSourcePath%\*.nsmap
del *.h
del %DestSourcePath%\*.h
del *.c
del %DestSourcePath%\*.c
del *.cpp
del %DestSourcePath%\*.cpp
if "%1"=="-d" goto 1

if %MFlag% EQU 1 (
  echo "generate c %OnVifHFile%"
  %GSoapBinPath%\wsdl2h.exe %WSDLCFlag% -t %TypeMapFile% -o %OnVifHTempFile% %WSDLFiles%
) else (
  echo "generate c++ %OnVifHFile%"
  %GSoapBinPath%\wsdl2h.exe %WSDLCPPFlag% -t %TypeMapFile% -o %OnVifHTempFile% %WSDLFiles%
)

if not exist "%OnVifHTempFile%" goto 2
echo #import "wsse.h" >> %OnVifHFile%
copy %OnVifHFile%+%OnVifHTempFile%
if not exist "%OnVifHFile%" goto 2
del %OnVifHTempFile%
echo "generate %OnVifHFile% success"

if %MFlag% EQU 1 (
  echo "soapcpp generate c Onvif source code" 
  %GSoapBinPath%\soapcpp2.exe %SOAPCFlag% -d%DestSourcePath% -I%GSoapSPath%\import;%GSoapSPath%\custom;%GSoapSPath% %OnVifHFile%
) else (
  echo "soapcpp generate c++ Onvif source code" 
  %GSoapBinPath%\soapcpp2.exe %SOAPCPPFlag% -d%DestSourcePath% -I%GSoapSPath%\import;%GSoapSPath%\custom;%GSoapSPath% %OnVifHFile%
)

if not exist "%DestSourcePath%\wsdd.nsmap" goto 3
del "%OnVifHFile%"
echo "generate Onvif source code success" 

echo "copy stdsoap2 files"
copy "%GSoapSPath%\stdsoap2.h" "%DestSourcePath%\stdsoap2.h"
if %MFlag% EQU 1 (
  copy "%GSoapSPath%\stdsoap2.c" "%DestSourcePath%\stdsoap2.c"
) else (
  copy "%GSoapSPath%\stdsoap2.cpp" "%DestSourcePath%\stdsoap2.cpp"
)
goto 1

:2
echo "generate %OnVifHFile% fail"
goto 1

:3
echo "generate Onvif source code fail"
goto 1

:help
echo generate onvif source code release 1.0
echo Usage: runwsdl [-h] [-l c level]
echo -h display help info
echo -l language level, c is c language, cpp is c++ language
echo -d clean generated source code
goto 1

:1 


copy stdsoap2.h等必须带引号,因为目标目录名有带++,不带引号,copy无法识别

12.在soapServer.c将SOAP_ENV__Fault部分代码加if 0注释掉
SOAP_FMAC5 int SOAP_FMAC6 soap_serve_request(struct soap *soap)
{
	soap_peek_element(soap);
#if 0
	if (!soap_match_tag(soap, soap->tag, "SOAP-ENV:Fault"))
		return soap_serve_SOAP_ENV__Fault(soap);
#endif

#if 0
SOAP_FMAC5 int SOAP_FMAC6 soap_serve_SOAP_ENV__Fault(struct soap *soap)
{	struct SOAP_ENV__Fault soap_tmp_SOAP_ENV__Fault;
	soap_default_SOAP_ENV__Fault(soap, &soap_tmp_SOAP_ENV__Fault);
	soap->encodingStyle = NULL;
	if (!soap_get_SOAP_ENV__Fault(soap, &soap_tmp_SOAP_ENV__Fault, "SOAP-ENV:Fault", NULL))
		return soap->error;
	if (soap_body_end_in(soap)
	 || soap_envelope_end_in(soap)
	 || soap_end_recv(soap))
		return soap->error;
	soap->error = SOAP_ENV__Fault(soap, soap_tmp_SOAP_ENV__Fault.faultcode, soap_tmp_SOAP_ENV__Fault.faultstring, soap_tmp_SOAP_ENV__Fault.faultactor, soap_tmp_SOAP_ENV__Fault.detail, soap_tmp_SOAP_ENV__Fault.SOAP_ENV__Code, soap_tmp_SOAP_ENV__Fault.SOAP_ENV__Reason, soap_tmp_SOAP_ENV__Fault.SOAP_ENV__Node, soap_tmp_SOAP_ENV__Fault.SOAP_ENV__Role, soap_tmp_SOAP_ENV__Fault.SOAP_ENV__Detail);
	if (soap->error)
		return soap->error;
	return soap_closesock(soap);
}
#endif

13.修改soapH.h,将soap_default_xsd_duration, soap_out_xsd__duration,soap_in_xsd__duration注释掉,重新定义
// SOAP_FMAC1 void SOAP_FMAC2 soap_default_xsd__duration(struct soap*, LONG64 *);
#define soap_default_xsd__duration(soap, a) soap_default_unsignedLONG64(soap, (ULONG64 *)a)

// SOAP_FMAC1 int SOAP_FMAC2 soap_out_xsd__duration(struct soap*, const char*, int, const LONG64 *, const char*);
#define soap_out_xsd__duration(soap,a,b,c,d) soap_out_unsignedLONG64(soap, a, b, (ULONG64 *)c, d)

// SOAP_FMAC1 LONG64 * SOAP_FMAC2 soap_in_xsd__duration(struct soap*, const char*, LONG64 *, const char*);
#define soap_in_xsd__duration(soap, a, b, c) (LONG64*)soap_in_unsignedLONG64(soap,a,(ULONG64 *)b,c)






你可能感兴趣的:(c,gsoap,onvif)