资讯详情

使用gSOAP生成ONVIF框架协议(离线方式)

使用gSOAP生成ONVIF框架协议(离线方式)

  • 1. 简单介绍
  • 2. 写作目的
  • 3. 主要内容
    • 3.1 从在线生成到离线生成
    • 3.2 离线生成步骤
  • 4. 已完成的资源

1. 简单介绍

简介:ONVIF标准是一种使用SOAP实现和Web Services一般来说,交互协议需要我们使用XML基于此格式和类服务器BS架构的通信,而这种XML格式就是由XML Schema来约定的,这种约定接口的文件就叫WSDL(Web Services Description Language,网络服务描述语言)。

想要理解gSOAP和ONVIF协议建议仔细查看博客:在这里,这位大神真的讲得够详细了。

2. 写作目的

首先,我不得不嘲笑国内技术文档的环境(我不是所有人,或者有很多人为我们铺平道路),许多博客相互转发,从只有几个博客,内容相似。关于采用gSOAP生成onvif协议C 我的方式不同于徐振坪大神的内容。在这里,我还想推荐另一个博客点。我也在陈元荣博客的基础上实现了离线生成的方式,但他有点粗糙,不太详细。我只是把这两位大神的方式结合起来,希望对大家有所帮助。

3. 主要内容

3.1 从在线生成到离线生成

我一直想用在线生成onvif但是gSOAP不支持SSL啊,需要重新编译支持SSL的gSOAP需要工具OpenSSL结果发现了几个链接库OpenSSL官网上有几个没有给我们编译的库,需要编译OpenSSL,几天受不了了,决定试试离线生成的方法。

所谓的离线方式是我们手动下载onvif官网上的wsdl文件,然后重新创建无加密连接,供自己使用gSOAP使用。

3.2 离线生成步骤

1、我们下载gSOAP工具,gSOAP官方网址:http://www.cs.fsu.edu/~engelen/soap.html。我下载的是gsoap_2.8.114,压缩包。

2.我们粗略下载wsdl文件,必须下载不完整,但不要害怕我们以后生成会有提示,有点多,但不是很多。进入网页后,右键单击保存。

http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.onvif.org/onvif/ver10/events/wsdl/event.wsdl http://www.onvif.org/onvif/ver10/display.wsdl http://www.onvif.org/onvif/ver10/deviceio.wsdl http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver20/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl http://www.onvif.org/onvif/ver10/receiver.wsdl http://www.onvif.org/onvif/ver10/recording.wsdl http://www.onvif.org/onvif/ver10/search.wsdl http://www.onvif.org/onvif/ver10/replay.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl http://www.onvif.org/onvif/ver10/schema/onvif.xsd http://www.onvif.org/ver10/actionengine.wsdl http://www.onvif.org/ver10/pacs/accesscontrol.wsdl http://www.onvif.org/ver10/pacs/doorcontrol.wsdl http://www.onvif.org/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl http://www.onvif.org/ver10/accessrules/wsdl/accessrules.wsdl http://www.onvif.org/ver10/credential/wsdl/credential.wsdl http://www.onvif.org/ver10/schedule/wsdl/schedule.wsdl http://www.onvif.org/ver10/pacs/types.xsd

3、 我们将下载的文件放在相应的文件夹下,例如: http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl 我们创造一个onvif文件夹(我创建的名字),再创建一个ver10文件夹,然后在里面创建…确保remotediscovery.wsdl路径相同,如下。 在这里插入图片描述

4.最后,我们得到了一个文件夹,然后我们重新创建了一个叫做文件夹的文件夹onvifCode,接着把gSOAP复制文件。

gsoap_2.8.45\gsoap-2.8\gsoap\bin\win32\soapcpp2.exe gsoap_2.8.45\gsoap-2.8\gsoap\bin\win32\wsdl2h.exe gsoap_2.8.45\gsoap-2.8\gsoap\stdsoap2.c gsoap_2.8.45\gsoap-2.8\gsoap\stdsoap2.h gsoap_2.8.45\gsoap-2.8\gsoap\typemap.dat gsoap_2.8.45\gsoap-2.8\gsoap\import gsoap_2.8.45\gsoap-2.8\gsoap\custom\

onvif.h不用担心后生成。

4.此时,我们需要建立反向代理web这样我们就可以通过服务器http访问我们的wsdl我在这里采用文件Nginx (engine x),想知道百度挺全的。 Nginx官网:http://nginx.org/en/download.html 下载后找到nginx-1.20.0\nginx-1.20.0\conf\nginx.conf,可以进行相关配置,这里我就不动了:访问时http://217.0.0.1:80 就是root路径,就是html路径(你可以在根目录下看到html文件夹),我们刚刚创建了它ver10、ver20放进去。

然后我们用windows的终端启动cmd.exe,确保刚刚创建的当前路径onvifCode目录下: 6、然后输入

wsdl2h -P -x -c -s -t ./typemap.dat -o onvif.h http://127.0.0.1:80/ver10/nework/wsdl/remotediscovery.wsdl http://127.0.0.1:80/ver10/device/wsdl/devicemgmt.wsdl http://127.0.0.1:80/ver10/events/wsdl/event.wsdl http://127.0.0.1:80/ver10/display.wsdl http://127.0.0.1:80/ver10/deviceio.wsdl  http://127.0.0.1:80/ver20/imaging/wsdl/imaging.wsdl http://127.0.0.1:80/ver10/media/wsdl/media.wsdl  http://127.0.0.1:80/ver20/media/wsdl/media.wsdl  http://127.0.0.1:80/ver20/ptz/wsdl/ptz.wsdl  http://127.0.0.1:80/ver10/receiver.wsdl http://127.0.0.1:80/ver10/recording.wsdl http://127.0.0.1:80/ver10/search.wsdl  http://127.0.0.1:80/ver10/replay.wsdl  http://127.0.0.1:80/ver20/analytics/wsdl/analytics.wsdl   http://127.0.0.1:80/ver10/analyticsdevice.wsdl http://127.0.0.1:80/ver10/schema/onvif.xsd http://127.0.0.1:80/ver10/actionengine.wsdl http://127.0.0.1:80/ver10/pacs/accesscontrol.wsdl   http://127.0.0.1:80/ver10/pacs/doorcontrol.wsdl   http://127.0.0.1:80/ver10/advancedsecurity/wsdl/advancedsecurity.wsdl   http://127.0.0.1:80/ver10/accessrules/wsdl/accessrules.wsdl   http://127.0.0.1:80/ver10/credential/wsdl/credential.wsdl   http://127.0.0.1:80/ver10/schedule/wsdl/schedule.wsdl  http://127.0.0.1:80/ver10/pacs/types.xsd

会出现报错,缺少文件,这时候我们下载对应文件补充到对应目录下,我们再重新生成onvif.h,这里记住每次重新生成的时候要把原来的onvif.h删掉。 7、我们按照这个博客https://blog.csdn.net/benkaoya/article/details/72466827的第三步开始。 ,有些ONVIF接口调用时需要携带认证信息,要使用soap_wsse_add_UsernameTokenDigest函数进行授权,所以要在onvif.h头文件开头加入

#import "wsse.h"

如果onvif.h不加入#import “wsse.h”,使用soap_wsse_add_UsernameTokenDigest函数会导致编译出错(错误信息如下):

wsse2api.c(183): error C2039: “wsse__Security”: 不是“SOAP_ENV__Header”的成员

$ soapcpp2 -2 -C -L -c -x -Iimport -Icustom -d onvif/ onvif.h

$ soapcpp2 -2 -C -L -c -x -Iimport -Icustom -d onvif/ onvif.h

wsa5.h(288): **ERROR**: service operation name clash: struct/class 'SOAP_ENV__Fault' already declared at wsa.h:273

之所有会出现这个错误,是因为onvif.h头文件中同时:

#import "wsdd10.h" // wsdd10.h中又#import "wsa.h"
#import "wsa5.h" // wsa.h和wsa5.h两个文件重复定义了int SOAP_ENV__Fault

解决方法:修改import\wsa5.h文件,将int SOAP_ENV__Fault修改为int SOAP_ENV__Fault_alex,再次使用soapcpp2工具编译就成功了,命令执行过程如下:

$ soapcpp2 -2 -C -L -c -x -Iimport -Icustom -d onvif/ onvif.h

**  The gSOAP code generator for C and C++, soapcpp2 release 2.8.45
**  Copyright (C) 2000-2017, Robert van Engelen, Genivia Inc.
**  All Rights Reserved. This product is provided "as is", without any warranty.
**  The soapcpp2 tool and its generated software are released under the GPL.
**  ----------------------------------------------------------------------------
**  A commercial use license is available from Genivia Inc., contact@genivia.com
**  ----------------------------------------------------------------------------


soap12.h(54): *WARNING*: option -1 or -2 overrides SOAP-ENV namespace


soap12.h(55): *WARNING*: option -1 or -2 overrides SOAP-ENC namespace

Using project directory path: onvif/
Saving onvif/soapStub.h annotated copy of the source interface file
Saving onvif/soapH.h serialization functions to #include in projects
Using wsdd service name: wsdd
Using wsdd service style: document
Using wsdd service encoding: literal
Using wsdd schema import namespace: http://schemas.xmlsoap.org/ws/2005/04/discovery
Saving onvif/wsdd.nsmap namespace mapping table
Using tdn service name: RemoteDiscoveryBinding
Using tdn service style: document
Using tdn service encoding: literal
Using tdn schema namespace: http://www.onvif.org/ver10/network/wsdl
Saving onvif/RemoteDiscoveryBinding.nsmap namespace mapping table
Using tds service name: DeviceBinding
Using tds service style: document
Using tds service encoding: literal
Using tds schema namespace: http://www.onvif.org/ver10/device/wsdl
Saving onvif/DeviceBinding.nsmap namespace mapping table
Using trt service name: MediaBinding
Using trt service style: document
Using trt service encoding: literal
Using trt schema namespace: http://www.onvif.org/ver10/media/wsdl
Saving onvif/MediaBinding.nsmap namespace mapping table
Saving onvif/soapClient.c client call stub functions
Saving onvif/soapC.c serialization functions

Compilation successful (2 warnings)

就是把对应的文件拷贝到生成目录里面去

$ cp stdsoap2.c stdsoap2.h plugin/wsaapi.c plugin/wsaapi.h custom/duration.c custom/duration.h  onvif/

soapC.c会调用到soap_in_xsd__duration函数,需要duration.c和duration.h文件。

后续示例代码会调用到soap_wsa_rand_uuid函数(用于生成UUID),需要wsaapi.c和wsaapi.h文件。 我 在onvif\stdsoap2.h中有命名空间「namespaces变量」的定义声明,如下所示:

extern SOAP_NMAC struct Namespace namespaces[];

但「namespaces变量」的定义实现,是在onvif\wsdd.nsmap文件中,为了后续应用程序要顺利编译,修改onvif\stdsoap2.c文件,在开头加入:

#include "wsdd.nsmap"

当然,你可以在其他源码中(更上层的应用程序源码)include,我这里是选择在stdsoap2.c中include

4. 已完成的资源

我自己也弄完了一版,大家可以走个捷径下载用用,一方面节省了大家的精力,反正也都会生成了,另一方面也没有必要非要在这个地方浪费时间,我也会根据大家需求不定时为大家更新资源。现成协议下载 https://download.csdn.net/download/zmxzmx110/19023799

标签: gsop光电传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台