onvif学习笔记1:环境准备

因为工作需要接触了onvif,但又不想只是直接使用别人的代码,想自己从头开始学,为不影响工作,在国庆期间作了一些研究。在了解这个东西前看了许多文章,但都一知半解,实然有一天发现,原来onvif就是那么一个东西。于是所有的框架、代码等等在脑海中清晰起来了。对于学习像onvif这些有参考代码、有标准文件的协议,最好方法是看文章、看代码、看协议文档。看文章,可以作一个初步的了解,知道这个是干什么的(之前帮同事编译的sip库就大约知道这些库主要用来做什么的,对它们有一个初步的了解)。看代码,就是即将进行实战的部分,毕竟,作为一个代码工人,必须与代码打交道,不看代码不行,只看代码不动手也不行。看协议文档,就是了解它们的原理,用标准协议来指导(在回家的火车上看onvif标准还是有帮助的,可以对整个onvif框架有所掌握)。

当然,着手写本文时,已经对onvif有了解,也写出了discovery响应函数,可以用工具搜索到,算有一些进展,后面就是按onvif的几个大块,分而治之。本篇文章是onvif学习系列的开篇。本系列所涉及的代码是综合了网上各类代码并经自己调试通过的,有些原始出处已无可考证,如果看到熟悉的代码不要惊讶,因为是抄人家的。我尽量给出我参考的一些资料的来源。

一、工具准备

工具有2个,一个是生成onvif代码的gsoap,另一个是测试工具,我使用的是ONVIF Device Test Tool,版本是12.12,这个工具很适合开发过程的调试,另外还有一个测试工具,安装包名称是odm-v2.0.5869.msi,可以看实时视频(ONVIF Device Test Tool也可以看,但在我的电脑上实时视频画面是一闪而过的,所以用另一个工具来看)。

gsoap可以在网上下载,最新版本是2.8.16。参考:http://www.cs.fsu.edu/~engelen/soap.html。下载的压缩包是zip,使用winrar(windows下)或gunzip(linux下)都可以解压。编译很简单,遵循linux工具安装三步曲:

./configure --prefix=/home/latelee/bin/gsoap --disable-ssl (注:如果不安装有ssl,则一定要禁止,否则编译出错)
make
make install

--prefix一定要根据实际情况写。官网下载的压缩包中有编译好的二进制文件,但我用了发现运行不了,所以只好自己编译了。

onvif的测试工具网上很多地方可以下载,这里不列举出来了。

 

二、生成代码

1.

将wsa5.h的SOAP_ENV__Fault改名,因为其它地方也存在这个结构体。

将编译好的wsdl2h、soapcpp2二进制文件以及typemap.dat、import目录、custom目录拷贝到自定义目录中,这里放到bin目录。
修改typemap.dat,在
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

2.

新建目录,用于onvif工程开发,这里是onvif_new。该目录与bin目录放到同一级目录。进行onvif_new目录,执行wsdl2h,生成onvif头文件:

../bin/wsdl2h -o onvif.h -c -s -t ../bin/typemap.dat 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/media/wsdl/media.wsdl
 

说明:onvif官网有许多wsdl文件,有一些是暂时用不到的,为了减少代码量,只选择必要的。可以到http://www.onvif.org/onvif/ver20/util/operationIndex.html上查看wsdl中包括哪些接口。-c表示生成c代码,-s表示不生成stl代码,-t指定了使用的typemap.dat文件。

3.

执行soapcpp2,生成相关代码框架

../bin/soapcpp2 -2 -c onvif.h -x -L -I ../bin/import -I ../bin/

-2表示生成soap 1.2绑定(直译的,原文是:generate SOAP 1.2 bindings),我就是因为这个问题被卡了半天,Probe搞了半天才发现是soap版本不以的问题。
-x表示不要xml文件
-L表示不产生soapClientLib.c、soapServerLib.c文件。

4.

拷贝gsoap压缩包中的duration.c/h、stdsoap2.c/h到工程目录,将生成的.nsmap文件复制为namespace.c。至此,已经生成了基本的代码框架,但还需要一些源文件才能编译通过(后面再讲到)。下面介绍到目前为止的文件:

onvif.h:第一条命令生成的
soapC.c:一坨代码,不用理它
soapStub.h:我们要实现的函数体在此文件有声明,soapClient.c、soapServer.c用到的函数在此文件。
stdsoap2.c/h:gsoap带的,不用理,编译要用到
duration.c/h:gsoap带的,不用理,编译要用到
soapClient.c:使用该文件中的一些发送的函数,如soap_send___wsdd__ProbeMatches
soapServer.c:服务端代码,只封装了大的框架,里面调用的函数要自己实现
wsdd.nsmap等等nsmap文件:命名空间的绑定,所有的nsmap文件内容都是一样的。
namespaces.c:命名空间,stdsoap2.c中有一个外部结构体,需要自己实现,不实现的话编译出错。

三、自定义

1.

为了使gsoap生成的文件与我们自己的代码区别开来,在源代码命名上作了一些修饰。目前主要额外添加如下文件:

myonvifLib.h/myonvifLib.c:对外的提供接口调用的,对外只提供启动onvif、停止onvif的接口,方便使用。
myonvifServer.h/myonvifServer.c:自己实现的soapStub.h中声明的函数
myonviface.h/myonviface.h:一些接口类的函数,如获取IP地址、MAC地址等等

2.

将soapStub.h中关于服务器端的函数声明拷贝到myonvifServer.c中,然后利用编辑器的替换功能修改该文件。

1)

将struct soap* 改为struct soap* soap。否则会报类似:
myonvifServer.c:5: 错误:省略了形参的名字
的错误。

2)

将函数声明修改成函数实现的形式,替换后的内容像下面的样子:

SOAP_FMAC5 int SOAP_FMAC6 SOAP_ENV__Fault(struct soap* soap, char *faultcode, char *faultstring, char *faultactor, struct SOAP_ENV__Detail *detail, struct SOAP_ENV__Code *SOAP_ENV__Code, struct SOAP_ENV__Reason *SOAP_ENV__Reason, char *SOAP_ENV__Node, char *SOAP_ENV__Role, struct SOAP_ENV__Detail *SOAP_ENV__Detail)
{
    onvif_debug(7, "--%s--\n", __func__);
    return SOAP_FAULT;
}

SOAP_FMAC5 int SOAP_FMAC6 __wsdd__Hello(struct soap* soap, struct wsdd__HelloType *wsdd__Hello)
{
    onvif_debug(7, "--%s--\n", __func__);
    return SOAP_FAULT;
}

注:如何替换就是考验个人的能力了,建议使用notepad++等稍高级一点的编辑工具来做。

 

至此,虽然还没有添加任何有用的代码,但至少可以编译通过了。准备环境已经做好了。

 

注:

本文并不是onvif教程,之所详细记录步骤,是为了描述从头开始学onvif的一些步骤,因为有些细节稍不注意,就会出现问题。

 

参考资料:

http://blog.csdn.net/ghostyu/article/details/8182516

(说明:这篇文章说到:“SOAP1.1和SOAP1.2所使用的SOAP-ENV是不同的,ONVIF使用的是SOAP1.1,如果soapcpp2产生的nsmap文件中的SOAP-ENV是SOAP1.2版本的话,那么OnvifTestTool是不会识别设备发出的SOAP消息的。”,经过我的测试,发现必须使用1.2版本,我就是因为这个问题卡了半天)

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值