基于Linux C 的ONVIF Profile T 协议服务器端实现备忘

本文介绍了使用C语言实现ONVIF Profile T协议服务器端的开发过程,包括准备事项、设备兼容性检查、Gsoap编译与ONVIF框架代码生成等关键步骤,并强调了在开发过程中遇到的问题及解决方案。

之前在做ONVIF Profile S的服务器端,用的是C++, 新的项目要使用H265,新的支持H265的协议Profile T已经发布(应该是2018年9月左右)。就准备用C语言重新写一套,目前主体框架和主要功能已经实现完成,记录下开发过程中注意事项。

开发之前需要了解的和准备的。

PC客户端方面, ONVIF Device Manager不支持Profile T和H265, 可以用来调试Profile S的内容,毕竟这部分差不多。ONVIF Device Test Tool目前最新版本18.12, 已经支持Profle T, 但是应该还没有liveview支持。

NVR方面,目前手上有大华和海康的某NVR。其中大华NVR可以支持Profile T, 海康的不支持,海康支持的H265是通过media.wsdl实现的,不算标准的Profile T协议。

基于Profile T协议, 以下是初步判断设备是否支持Profile T。

1. ONVIF Discovery,  Scopes 必须包含 onvif://www.onvif.org/Profile/T,Types包含 tds:Device。

2. Profile T中Device.Capabilities并没有那么重要,在Extension加入DeviceIO. 另外需要检测的是Device.GetServices 和 Device.ServiceCapabilities。Device.GetServices中需要支持HttpDigest, 支持Media2 Service(名称自定义,namespace一致就行). Device.ServiceCapabilities 需要包含 Media2, Imaging, DeviceIO。

3. Event.ServiceCapabilities 中包含 MaxPullPoints。

4. Media2.ServiceCapabilities 中包含 MaximumNumberOfProfiles。

5. Event.GetEventProperties中包含 MessageContentFilterDialect。

6. Media2.ServiceCapabilities 中支持 Real-time Streaming RTP/UDP RTP/RTSP/HTTP RTP-Multicast/UDP。

7. Media2 中encoding 支持 H264/H265。

8. Media2.GetSnapshotUri 支持。

9. Event.GetEventProperties中包含 Motion Alarm,  至少包含以下之一: Image Too Blurry,  Dark, Bright, Global Scene Change。

10. DeviceIO.GetServiceCapabilities 中包含 VideoSources。

ONVIF 框架代码是使用Gsoap生成, 版本为2.8.85。

1. Gsoap 编译

./configuration

make

两个可执行文件 wsdl2h soapcpp2

2. ONVIF 框架代码生成

复制gsoap/typemap.dat 到ONVIF 目录

typemap.dat 中添加

tr2     = "http://www.onvif.org/ver20/media/wsdl"

tns1    = "http://www.onvif.org/ver10/topics"

这两个namespace 分别是为了Media2 service, Event

另外为了ONVIF 鉴权,在onvif.h中加入wsse.h, 需要在typemap.dat中加入

[

#import "wsse.h"

]

需要用到的wsdl文件, 不需要device.wsdl, 因为在解析deviceio.wsdl 时会自动下载,否则会生成一些重复的函数。

http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl

http://www.onvif.org/ver10/events/wsdl/event.wsdl

http://www.onvif.org/ver10/deviceio.wsdl

http://www.onvif.org/ver20/imaging/wsdl/imaging.wsdl

http://www.onvif.org/ver20/media/wsdl/media.wsdl

生成命令

wsdl2h -o $@ -c -s -t ../typemap.dat $(WSDL_FILES)

soapcpp2 -L -c $@ -x -Ec -Ed -I $(GSOAP_ROOT)/import -I $(GSOAP_ROOT)

(-Ec -Ed 是为了生成 soap_dup_T soap_del_T, 我在调试过程中soap_dup_T执行多次会出现丢数据情况,慎用 )

mv wsdd.nsmap nsmap.h

rm -f *.nsmap

出现SOAP_ENV_Fault错误,注释掉 gsoap/import/wsa5.h 中 int SOAP_ENV_Fault 函数。

EVP_MD_CTX未定义 , 编译选项加上 -DWITH_DOM -DWITH_OPENSSL    -lcrypto –lssl

复制以下文件到ONVIF目录, 以及相应的h文件:

stdsoap2.h stdsoap2.c dom.c  plugin/httpda.c  plugin/md5evp.c  plugin/wsseapi.c  plugin/smdevp.c plugin/threads.c  import/wsa5.h

代码框架生成后,需要实现的ONVIF 函数声明在 soapStub.h 中

SOAP_FMAC5 int SOAP_FMAC6 __xx__Get

需要具体实现,当然可以先返回 SOAP_OK, 后面慢慢搞。返回SOAP_OK前,需要鉴权,然后调用soap_wsse_delete_Security(soap) 删除 header。

Probe 相关函数实现 soap_send___wsdd__ProbeMatches

Hello 函数 soap_send___wsdd__Hello 

Bye 函数 soap_send___wsdd__Bye

struct wsdd__HelloType 和 struct wsdd__ByeType 中参数最好都赋值,否则可能会 crash。

另外,慎用soap_copy, 这个函数copy soap 结构体 不完全,会出现namespace 检测错误,初步解决是在之后再调用 soap_copy_stream。

如果在soap_begin_serve 函数后开线程,传给线程的 soap 结构体数据也是不完全的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值