- 收藏
- 点赞
- 分享
- 举报
ONVIF协议实现1:Server端Discovery的实现详解
本帖最后由 goodman 于 2014-12-31 21:37 编辑
最近在做摄像机ONVIF的协议,看了几天文档调了点代码和大家分享下,下步准备实现RTSP的流地址的获取。 附件里面是我的完整代码工程,使用的是arm-linux-gcc,代码也可以在X86的Linux上跑,只要将Makefile里面额CC=arm-linux-gcc换成gcc即可
工作平台及工具: Ubuntu:12.04 + arm-linux-gcc/gcc + OnvifTestTool12.12 gsoap下载:http://www.cs.fsu.edu/~engelen/soap.html 目前的最新版本为:gsoap2.8.21
1.搞定工具: 首先需要做的是提取工具一共有3样: soapcpp2 wsdl2h typemap.dat 我下载的的gsoap里面的typemap.dat已经包含了WS-Discovery的支持因此不需要再像网上那样去添加ONVIF支持了 下载好的源码解压出来,到gsoap-2.8/gsoap/bin目录里面一看,没有我们需要的soapcpp2 wsdl2h: [attach]2065[/attach] 没有我们只好自己编译一个了,看了下他的README.txt里面有这么一句话(PS:我比较喜欢看项目里面的README能帮助我们解决很多问题). For other platforms: see installation instructions INSTALL.txt in the root dir. 到根目录里面看下INSTALL.txt知道了怎么编译了 cd gsoap/src make -f MakefileManual cd gsoap/wsdl make -f MakefileManual
- Remotediscovery.wsdl产生onvif.h头文件 对于这里我们只要实现设备发现的功能,所以我们只需要Remotediscovery.wsdl这一个wsdl就可以了 ./wsdl2h -o onvif.h -c -s -k -t ./typemap.dat http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl 生成的时候会报SOAP_ENVFault 重定义的错误,将gsoap-2.8/gsoap/import/wsa5.h里面的第277行的SOAP_ENV__Fault改为SOAP_ENVFault_ex就可以了
3.生成ONVIF的框架代码 ./soapcpp2 -c onvif.h -x -d ./ -I ${HOME}/workspace/source/gsoap-2.8/gsoap/import -I ${HOME}/workspace/source/gsoap-2.8/gsoap/ 这里的${HOME}/workspace/source/gsoap-2.8/gsoap/import 和${HOME}/workspace/source/gsoap-2.8/gsoap/注意修成自己的。 这里会报
4.拷贝相关代码 建立一个onvif_test的目录将${HOME}/workspace/source/gsoap-2.8如下文件拷贝过来过来 gsoap/dom.c gsoap/stdsoap2.c gsoap/stdsoap2.h gsoap/custom/duration.c gsoap/plugin/mecevp.c gsoap/plugin/mecevp.h gsoap/plugin/smdevp.c gsoap/plugin/smdevp.h gsoap/plugin/threads.c gsoap/plugin/threads.h gsoap/plugin/wsaapi.c gsoap/plugin/wsaapi.h gsoap/plugin/wsseapi.c gsoap/plugin/wsseapi.h gsoap/plugin/wsddapi.c gsoap/plugin/ wsddapi.h 这些代码会帮我很多工作的,下面就知道了
5.实现关键代码 [code]soap_wsdd_mode wsdd_event_Probe(struct soap soap, const char MessageID, const char ReplyTo, const char Types, const char Scopes, const char MatchBy, struct wsdd__ProbeMatchesType *matches) {
if 0
printf("%s,%d\n",FUNCTION, LINE); printf("MessageID:%s\n", MessageID); printf("ReplyTo:%s\n", ReplyTo); printf("Types:%s\n", Types); printf("Scopes:%s\n", Scopes); printf("MatchBy:%s\n", MatchBy);
endif
soap_wsdd_init_ProbeMatches(soap, matches); soap_wsdd_add_ProbeMatch(soap, matches, "urn:uuid:464A4854-4656-5242-4530-313035394100", "tdn:NetworkVideoTransmitter", "onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/type/ptz onvif://www.onvif.org/type/video_analytics onvif://www.onvif.org/hardware/HD-IPCAM onvif://www.onvif.org/location/country/china onvif://www.onvif.org/name/IPCAM", NULL, "http://192.168.1.22/onvif/device_service",10); return SOAP_WSDD_MANAGED;
}[/code] 这个就是回应设备发现工具的主要代码,是不是很简单如果不适用wsddapi.c 里面的代码将要写一大推的填充代码具体,具体可以看最后面的参考链接。 6.实现的main函数 [code]
include "soapH.h"
include "wsdd.nsmap"
include "wsddapi.h"
include
include <sys/types.h> / See NOTES /
include <sys/socket.h>
include
include
int main(int argc, char argv[])
{
int m, s;
struct ip_mreq mcast;
struct soap soap;
soap_init2(&soap, SOAP_IO_UDP | SOAP_IO_FLUSH, SOAP_IO_UDP|SOAP_IO_FLUSH);
soap_set_namespaces(&soap, namespaces);
soap_set_mode(&soap, SOAP_C_UTFSTRING);
soap.bind_flags = SO_REUSEADDR;
soap.connect_timeout = 0;
soap.recv_timeout = 0;
soap.send_timeout = 0;
soap_register_plugin(&soap, soap_wsa); //这个很重要,我分析了很久才得出的
// 打开调试信息
soap_set_recv_logfile(&soap, "./log/recv.xml");
soap_set_sent_logfile(&soap, "./log/send.xml");
soap_set_test_logfile(&soap, "./log/test.log");
if(!soap_valid_socket(soap_bind(&soap, NULL, 3702, 16)))
{
soap_print_fault(&soap, stderr);
exit(1);
}
mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
mcast.imr_interface.s_addr = inet_addr("0.0.0.0");
if(setsockopt(soap.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char)&mcast, sizeof(mcast)) < 0) {
printf("setsockopt error!\n");
return 0;
}
//成功绑定之后,便开始监听
for (;;) {
//监听直到有连接请求
soap_wsdd_listen(&soap, 0);
soap_destroy(&soap);
soap_end(&soap);
fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
}
soap_done(&soap);
return 0;
}
[/code]
整体的主函数就是这样,需要注意的一点是需要在wsdd.nsmap里多添加一个命名空间
{"tds", "http://www.onvif.org/ver10/device/wsdl", NULL, NULL},
7.测试结果 [attach]2066[/attach] 消息格式: [code] <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding" x mlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery" xmlns:tdn="http://www.onvif.org/ver10/network/wsdl" xmlns:tds="http://www.onvif.org/ver10/device/wsdl">
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
-
2015-01-09 21:52:35
-
2015-01-05 10:30:27
-
2020-08-15 15:38:39
-
2015-01-05 21:26:10
-
2015-04-28 14:43:42
-
2015-02-02 11:38:04
-
2018-12-11 17:25:13
-
2018-08-23 17:26:08
-
2023-12-17 13:51:14
-
2019-01-18 15:48:46
-
2019-10-11 10:44:22
-
2016-03-27 17:05:09
-
2019-01-22 11:49:16
-
2018-08-28 13:24:28
-
2015-08-26 10:51:06
-
2018-11-22 14:56:07
-
2015-12-18 15:45:27
-
2017-09-05 11:49:45
-
2023-02-07 17:08:52
-
5Hi3516CV610 如何使用SD卡升级固件
-
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板子运行自己编码的程序
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明