1、 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.w
2、sdl 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 (
3、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
4、 -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 even
5、t.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 ev
6、ent.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_
7、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"); }
8、 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
9、 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, "-d
10、nrd: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_end
11、point); 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);
12、 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_envel
13、ope_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
14、 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_w
15、sse_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 获取所有能力集 获取设备能力集 获取事件能力集 获取图象能力集 获取媒体能力集 获取主机名字 设置主机名 获取网络接口信息 设置网络接口信息 获取网络协议 获取网关 设置网关






