- 收藏
- 点赞
- 分享
- 举报
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]
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
-
2015-01-05 21:26:10
-
2017-09-05 11:49:45
-
2020-08-15 15:38:39
-
2014-12-31 21:32:49
-
2019-09-30 18:56:47
-
2016-04-08 19:03:38
-
2017-10-26 10:15:31
-
2023-11-26 11:27:41
-
122024-01-04 16:24:59
-
2013-06-28 22:35:45
-
2018-12-11 10:20:04
-
2013-07-11 12:48:42
-
2018-08-28 13:24:28
-
2017-11-01 10:48:13
-
2015-12-18 15:45:27
-
2013-01-27 14:45:58
-
2019-01-22 11:49:16
-
2016-01-07 10:53:12
-
2021-06-19 16:05:21
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
-
10求HI3519DV500_SDK_V2.0.1.1
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明