goodman

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman  发布于  2015-01-09 21:52:35
采纳率 0%
30个问答
wooshang@126.com
17227

ONVIF协议实现3:整合Discovery和码流地址用ONVIF Device Manager测试

   

[i=s] 本帖最后由 goodman 于 2015-1-9 21:57 编辑 [/i]

工作平台及工具: Ubuntu:12.04 + gcc + OnvifTestTool12.12 gsoap下载:http://www.cs.fsu.edu/~engelen/soap.html PC:live555.exe + test.264 目前的最新版本为:gsoap2.8.21 经过前2编文章的的分析对于掌握ONVIF的实现应该没有什么问题了,本来是不想写这边文章的,但是我在整合Discovery和码流地址的时候还是遇到了不少问题 想想将来有某个小伙伴按照我的文章来学习ONVIF看到GC的部分突然没有了这是很不好的,做事情要有始有终,让我们把它结束吧。

1.生成源码 这次生成的代码需要3个WSDL了 ./wsdl2h -o onvif.h -c -s -t ./typemap.dat http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsd http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl ./soapcpp2 -c onvif.h -x -d ./ -I ${HOME}/workspace/source/gsoap-2.8/gsoap/import -I ${HOME}/workspace/source/gsoap-2.8/gsoap/

2.整理流程 整个程序的运行流程大概是这个样子,嗯,差不多就是这个样子。 [attach]2123[/attach] 3.整理代码 将设备发现和码流获取部分的代码分别整理到2个单独的文件里面去,接口函数如下: /初始化设备搜索的代码/ [code] int discoveryInit(struct DiscoveryApp disApp); void discoveryFini(struct DiscoveryApp disApp); int discoveryRun(struct DiscoveryApp *disApp);

/初始化码流地址部分的代码/ int gsoapAppInit(struct GsoapApp app); void gsoapAppFini(struct GsoapApp app); int gsoapAppRun(struct GsoapApp app, int forked); [/code] 那么整个主函数就比较干净了(当然我给的是示例代码,容错我想大家都知道怎么加) [code] struct GsoapApp gApp = NULL; struct DiscoveryApp disApp = NULL; int main(int argc, char argv[]) { gApp = (struct GsoapApp)calloc(1, sizeof(gApp)); disApp = (struct DiscoveryApp)calloc(1, sizeof(disApp));

discoveryInit(disApp); discoveryRun(disApp); gsoapAppInit(gApp); gsoapAppRun(gApp, 1);

while(1) { sleep(1); } discoveryFini(disApp); gsoapAppFini(gApp);

free(gApp); free(disApp); return 0; } [/code] 4.错误处理 本以为到这里编译下就行了,因为我们在先前已经调通了Discovery和流地址的代码写好Makefile后一编译错误了 问题1链接错误: [code] wsddapi.c: In function ‘soap_wsdd_Hello’: wsddapi.c:466:6: error: ‘struct wsddHelloType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘soap_wsdd_Bye’: wsddapi.c:531:6: error: ‘struct wsddByeType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘soap_wsdd_Resolve’: wsddapi.c:688:6: error: ‘struct wsddResolveType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘soap_wsdd_add_ProbeMatch’: wsddapi.c:796:4: error: ‘struct wsddProbeMatchType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘soap_wsdd_ResolveMatches’: wsddapi.c:892:8: error: ‘struct wsddResolveMatchType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘wsddHello’: wsddapi.c:1132:13: error: ‘struct wsddHelloType’ has no member named ‘wsa5EndpointReference’ wsddapi.c:1140:1: error: ‘struct wsddHelloType’ has no member named ‘wsa5EndpointReference’ wsddapi.c:1162:10: error: ‘struct wsddHelloType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘wsddBye’: wsddapi.c:1200:11: error: ‘struct wsddByeType’ has no member named ‘wsa5EndpointReference’ wsddapi.c:1208:1: error: ‘struct wsddByeType’ has no member named ‘wsa5EndpointReference’ wsddapi.c:1230:8: error: ‘struct wsddByeType’ has no member named ‘wsa5EndpointReference’ wsddapi.c: In function ‘wsddResolve’: wsddapi.c:1386:15: error: ‘struct wsddResolveType’ has no member named ‘wsa5EndpointReference’ wsddapi.c:1402:12: error: ‘struct wsddResolveType’ has no member named ‘wsa5EndpointReference' [/code] 一下子报了这么多错误,是链接找不到wsa5__EndpointReference,这个情况一般是只声明了,没有定义才会在链接的时候报错。 通过grep查找定义,发现是因为soapStub.h第15行定义了SOAP_WSA_2005宏导致的。 [code]

ifndef soapStub_H

define soapStub_H

define SOAP_WSA_200408

define SOAP_NAMESPACE_OF_wsdd "http://schemas.xmlsoap.org/ws/2005/04/discovery"

//#define SOAP_WSA_2005 注释这一行就可以了

define SOAP_NAMESPACE_OF_tds "http://www.onvif.org/ver10/device/wsdl"

[/code] 再次make出现了错误 [code] gsoapapp.o:(.data+0x0): multiple definition of `namespaces' discovery.o:(.data+0x0): first defined here collect2: ld returned 1 exit status [/code] 这是因为我们使用了2个soap服务,每个sopa服务都要设置自己的命名空间见discovery.c和gsoapapp.c soap_set_namespaces(&app->soap, namespaces); 将其中的一个名字改掉就好了,我这里改的是gsoapapp.c soap_set_namespaces(&app->soap, namespaces);-->soap_set_namespaces(&app->soap, namespaces1); 把MediaBinding.nsmap里面的namespaces改为namespaces1问题1就彻底解决了。

问题2无法搜索到设备: 使用ONVIF Device Manager死也搜索不到设备ONVIF Device Test Tool也不行设备端提示如下: [attach]2120[/attach] 这个Discovery明明是调通的怎么就不行了呢?翻看log/test.log里面我们发现有这些日志 [code] stdsoap2.c(7729): malloc(20) = 0xb6401b10 stdsoap2.c(7729): malloc(16) = 0xb6401b40 stdsoap2.c(7729): malloc(24) = 0xb6400b40 wsaapi.c(989): soap_wsa_fault_subcode(faultsubcode=wsa5:MessageAddressingHeaderRequired, faultstring=A required header representing a Message Addressing Property is not present.) stdsoap2.c(7729): malloc(76) = 0xb6401b88 [/code] 经过和第一篇那个单独的Discovery工程里面的日志对比发现是命名空间的问题。打开wsdd.nsmap把命名空间修改为下面的 [code]

include "soapH.h"

SOAP_NMAC struct Namespace namespaces[] = { {"SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://schemas.xmlsoap.org/soap/envelope/", NULL}, {"SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://schemas.xmlsoap.org/soap/encoding/", NULL}, {"xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL}, {"xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL}, {"wsa", "http://schemas.xmlsoap.org/ws/2004/08/addressing", NULL, NULL}, {"wsdd", "http://schemas.xmlsoap.org/ws/2005/04/discovery", NULL, NULL}, {"tdn", "http://www.onvif.org/ver10/network/wsdl", NULL, NULL}, {"tds", "http://www.onvif.org/ver10/device/wsdl", NULL, NULL}, {NULL, NULL, NULL, NULL} }; [/code] 重新编译代码(make clean && make)再执行发现可以发现设备了,这样我们就实现了自动发现设备,自动获取ONVIF的流地址了。

5.运行截图 直接运行ONVIF Device Manager程序,这次不需要再在右下角手工添加了。对于系统的标示我填了一部分。 [attach]2121[/attach] 播放视频: [attach]2122[/attach]

6.总结 这样这个ONVIF系类的文章就算全部完成了,我们只要按照这个框架将其他的命令实现就能完整的做完ONVIF了。 这里大家看到了我们使用的ONVIF端口是8080,为什么要这个端口?这是因为我们的设备上需要用到WEB服务,而 WEB服务将80端口已经占了,不得不说这是个遗憾,目前使用gSOAP我还不清楚怎么把它和WEB整合在一起。当然 如果不借助gSOAP自己去实现ONVIF的话是可以解决的,但是那样要自己去解析xml数据那是比较繁琐的。

[attach]2124[/attach]

[attach]2124[/attach]

易百纳技术社区文件: onvif_over.tar.gz
下载
我来回答
回答12个
时间排序
认可量排序

david

33个粉丝

368

问答

253

专栏

229

资料

david 2015-01-10 22:57:42
认可0
赞,为啥不参见活动呢。:D

goodman

2个粉丝

30

问答

18

专栏

17

资料

goodman 2015-01-11 15:36:16
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=11154&ptid=5034]david 发表于 2015-1-10 22:57[/url]
赞,为啥不参见活动呢。[/quote]

哈哈,重在分享!:lol

kgui

0个粉丝

13

问答

0

专栏

4

资料

kgui 2015-01-11 18:46:24
认可0
顶 楼上。膜拜下。

dong_abc

0个粉丝

0

问答

0

专栏

0

资料

dong_abc 2015-04-21 10:04:15
认可0
高质量 帖子

hgz

0个粉丝

0

问答

0

专栏

0

资料

hgz 2016-12-21 11:51:25
认可0
有始有终 良心贴 必须赞

qn1532917771

0个粉丝

7

问答

0

专栏

0

资料

qn1532917771 2018-09-04 16:56:02
认可0
谢谢楼主!解决了我的问题

qn1532917771

0个粉丝

7

问答

0

专栏

0

资料

qn1532917771 2018-09-30 16:58:06
认可0
大神,我有个问题能否帮我一下,我用您的代码制作了一个ipc,但是我用一个支持onvif协议的上位机没法播放视频。提示soap_serve() error: "The data in element 'wsse:Security' must be understood but cannot be handled"
应该是我没有设置密码,而上位机必须输入密码导致的,请问一下,这个问题该怎么解决那?

tfh_jpcd

1个粉丝

4

问答

0

专栏

0

资料

tfh_jpcd 2018-11-22 14:40:29
认可0
学习学习。感谢楼主分享

qn1533967860

0个粉丝

0

问答

0

专栏

0

资料

qn1533967860 2019-04-02 21:27:24
认可0
感谢楼主分享

liucuqi

0个粉丝

0

问答

0

专栏

0

资料

liucuqi 2015-05-20 15:40:34
认可0
高手,膜拜!

hushuting_2012

0个粉丝

1

问答

0

专栏

0

资料

hushuting_2012 2019-04-03 23:01:08
认可0
不用gSOAP可以实现onvif吗

天最

1个粉丝

52

问答

0

专栏

2

资料

天最 2019-06-18 09:36:49
认可0
本帖最后由 天最 于 2019-6-18 09:58 编辑

顶顶顶:lol :lol :lol
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区