全部博文(776)
分类: LINUX
2013-07-11 13:51:58
onvif实现功能和经验
1) 设备匹配probe消息
SOAP_FMAC5 int SOAP_FMAC6 soap_serve___dndl__Probe(struct soap *soap)
{
….
把soap_put_d__ProbeMatchesType(soap, &dn__ProbeResponse, "dn:ProbeResponse", NULL) 改成soap_put_d__ProbeMatchesType(soap, &dn__ProbeResponse, "d:ProbeMatches", NULL)
….
}
2) 由analytics.wsdl ptz.wsdl devicemgmt.wsdl media.wsdl event.wsdl 生成头文件,在头文件中要加#import "import/wsse.h" ,为了实现安全接口
3) 安全验证用户
SOAP_FMAC3 int SOAP_FMAC4 soap_out_SOAP_ENV__Header(struct soap *soap, const char *tag, int id, const struct SOAP_ENV__Header *a, const char *type)
{
….
soap->mustUnderstand = 1;
if (soap_out_PointerTo_wsse__Security(soap, "wsse:Security", -1, &a->wsse__Security, ""))
return soap->error;
改为soap->mustUnderstand = 0;
if (soap_out_PointerTo_wsse__Security(soap, "wsse:Security", -1, &a->wsse__Security, ""))
return soap->error;
….
}
4) 生成.c文件
D:\onvif>soapcpp2 -2 -c -x -L -pws -I D:\gsoap-2.8\gsoap;d:\gsoap-2.8/gsoap/import/ ws.h
其中-2参数是选择onvif 1.2 版本, 如果选择-1消息通知就无法被onvif测试工具识别
5) 生成.c后缀名的文件全部改成.cpp文件
6) onvif要生成客户和服务端, 客户端主要是用来发送hello消息和消息通知接口
7) 生成头文件
D:\onvif>wsdl2h.exe –c -o ws.h -t typemap.dat -s analytics.wsdl ptz.wsdl devicemgmt.wsdl media.wsdl event.wsdl remotediscovery.wsdl imaging.wsdl
要在ws.h文件中增加 #import
"import/wsse.h" 这表明是安全接口
8) soapcpp2生成数个.nsmp命名空间文件,只需要用其中一个就可以(我们使用的EventBinding.nsmap)
9) 开发人员只需关注wsClient.c, wsServer.c这两个文件,可对他进行修改
10) 通过wsdl2h.exe –c -o ws.h -t typemap.dat -s analytics.wsdl ptz.wsdl devicemgmt.wsdl media.wsdl event.wsdl remotediscovery.wsdl imaging.wsdl 会报错误,不影响开发.
11) 设备发现的soap初试化必为 下列代码
soap_init1(&m_soap_entry,
SOAP_IO_UDP | SOAP_XML_IGNORENS);
struct ip_mreqn imreq;
imreq.imr_multiaddr.s_addr =inet_addr(MULTI_GROUPID);
imreq.imr_address.s_addr = htonl(INADDR_ANY);
imreq.imr_ifindex= 2;
m_soap_entry.version = 2;
m_soap_entry.send_timeout = 3; // 1s timeout
m_soap_entry.recv_timeout = 3; // 1s timeout
if (!soap_valid_socket(soap_bind(&m_soap_entry, NULL, 3702, 100)))
{
DEBUG_OUTPUT4("CDiscovery::Init soap_valid_socket error");
}
DEBUG_OUTPUT4("CDiscovery::Init soap_valid_socket success");
if (setsockopt(m_soap_entry.master, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq, sizeof(imreq))<0)
{
DEBUG_OUTPUT4("CDiscovery::Init setsockopt IP_ADD_MEMBERSHIP Error");
}
12) hello 消息发送必须为
struct soap *tsoap;
tsoap = soap_copy(&m_soap_entry);
Hello(tsoap, endpointReference);
把
if (soap_connect(soap, soap_endpoint, soap_action)
|| soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___dnrd__Hello(soap, &soap_tmp___dnrd__Hello, "-dnrd:Hello", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap)
|| soap_end_send(soap))
return soap_closesock(soap);
改为
if (soap_connect(soap, NULL, soap_action))
{
return soap_closesock(soap);
}
soap_set_endpoint(soap, soap_endpoint);
soap->error = SOAP_OK;
struct sockaddr_in peer;
peer.sin_family=AF_INET;
peer.sin_port=htons(soap->port);
peer.sin_addr.s_addr=inet_addr(soap->host);
memcpy(&soap->peer, &peer, sizeof(sockaddr_in));
soap->peerlen = sizeof(peer);
if(soap_envelope_begin_out(soap)
|| soap_putheader(soap)
|| soap_body_begin_out(soap)
|| soap_put___dnrd__Hello(soap, &soap_tmp___dnrd__Hello, "-dnrd:Hello", NULL)
|| soap_body_end_out(soap)
|| soap_envelope_end_out(soap)
|| soap_end_send(soap))
return soap_closesock(soap);
13) 开发人员要实现服务端所有接口,下面是部分接口(请参考wsClient.cpp 文件
SOAP_FMAC5 int SOAP_FMAC6 __dndl__Probe(struct soap*, struct d__ProbeType *dn__Probe, struct d__ProbeMatchesType *dn__ProbeResponse);
SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Hello(struct soap*, struct d__HelloType *dn__Hello, struct d__ResolveType *dn__HelloResponse);
SOAP_FMAC5 int SOAP_FMAC6 __dnrd__Bye(struct soap*, struct d__ByeType *dn__Bye, struct d__ResolveType *dn__ByeResponse);
14) 安全用户名和密码是采用openssl库和gsoap的自带的控件, 采用下列接口
soap_wsse_verify_Password
soap_wsse_verify_Timestamp
soap_wsse_get_Username
15) openssl 编译
tar zxvf openssl-0.9.8.tar.gz
cd openssl-0.9.8
./config no-asm --prefix=/opt/openssl os/compiler: /ToolChain/bin/
arm-none-linux-gnueabi-g++
make
make install
之后进入到/opt/openssl 拷贝头文件和库
16) 通过80端口发送流
首先要判断消息是onvif消息还是请求流消息, 通过MSG_PEEK来区分
如果是onvif消息就走onvif信令,否则走播流通道
Onvif已经实现功能
设备发送hello消息
设备接收hello消息
设备发现匹配相应
获取设备信息
设置系统时间
获取系统时间
软件出厂默认值恢复
系统重新启动
获取wsdlurl
获取所有能力集
获取设备能力集
获取事件能力集
获取图象能力集
获取媒体能力集
获取主机名字
设置主机名
获取网络接口信息
设置网络接口信息
获取网络协议
获取网关
设置网关