ONVIF专题--Onvif标准解读(2)--Core Spec::Device Discovery(2)

相关文章:
ONVIF专题--Onvif标准解读(2)--Core Spec::Device Discovery(1)
ONVIF专题--Onvif标准解读(2)--Core Spec::Device Discovery(3)

gSoap实现ONVIF的设备发现

1 依赖

  1. ONVIF相关的WSDL文件,对于设备发现,只需要用到remoteDiscovery.wsdl[http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl]即可
  2. gSoap的压缩包,找到/gsoap/bin/win32文件夹中的soapcpp2.exe以及wsdl2h.exe,以及在/gSoap目录下的typemap.dat文件,将这些文件放到一个文件夹下。
    :gSoap使用版本。因为ONVIF的DD是基于WS-Discovery1.0规范做的改动,建议使用2.8.80或2.8.81版本gsoap。另外官网下载gsoap时注意不要下载商业版本。开源GPLv2的版本路径:https://sourceforge.net/projects/gsoap2/

2 修改typemap.bat

tds        = "http://www.onvif.org/ver10/device/wsdl"

tev        = "http://www.onvif.org/ver10/events/wsdl"

tls        = "http://www.onvif.org/ver10/display/wsdl"

tmd        = "http://www.onvif.org/ver10/deviceIO/wsdl"

timg        = "http://www.onvif.org/ver20/imaging/wsdl"

trt        = "http://www.onvif.org/ver10/media/wsdl"

tptz        = "http://www.onvif.org/ver20/ptz/wsdl"

trv        = "http://www.onvif.org/ver10/receiver/wsdl"

trc        = "http://www.onvif.org/ver10/recording/wsdl"

tse        = "http://www.onvif.org/ver10/search/wsdl"

trp        = "http://www.onvif.org/ver10/replay/wsdl"

tan        = "http://www.onvif.org/ver20/analytics/wsdl"

tad        = "http://www.onvif.org/ver10/analyticsdevice/wsdl"

tdn        = "http://www.onvif.org/ver10/network/wsdl"

tt        = "http://www.onvif.org/ver10/schema"

 

#        OASIS recommended prefixes

wsnt        = "http://docs.oasis-open.org/wsn/b-2"

wsntw        = "http://docs.oasis-open.org/wsn/bw-2"

wsrfbf        = "http://docs.oasis-open.org/wsrf/bf-2"

wsrfr        = "http://docs.oasis-open.org/wsrf/r-2"

wsrfrw  = "http://docs.oasis-open.org/wsrf/rw-2"

wstop        = "http://docs.oasis-open.org/wsn/t-1"

 

#   WS-Discovery 1.0 remapping 

wsdd10__HelloType       = | wsdd__HelloType 

wsdd10__ByeType         = | wsdd__ByeType 

wsdd10__ProbeType       = | wsdd__ProbeType 

wsdd10__ProbeMatchesType    = | wsdd__ProbeMatchesType 

wsdd10__ProbeMatchType      = | wsdd__ProbeMatchType 

wsdd10__ResolveType     = | wsdd__ResolveType 

wsdd10__ResolveMatchesType  = | wsdd__ResolveMatchesType 

wsdd10__ResolveMatchType    = | wsdd__ResolveMatchType

 

#   SOAP-ENV mapping 

SOAP_ENV__Envelope  = struct SOAP_ENV__Envelope { struct SOAP_ENV__Header *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope 

SOAP_ENV__Header    = | struct SOAP_ENV__Header 

SOAP_ENV__Fault     = | struct SOAP_ENV__Fault 

SOAP_ENV__Detail    = | struct SOAP_ENV__Detail 

SOAP_ENV__Code      = | struct SOAP_ENV__Code 

SOAP_ENV__Subcode   = | struct SOAP_ENV__Subcode 

SOAP_ENV__Reason    = | struct SOAP_ENV__Reason

其中加色部分是添加的内容,用于对内容加上ONVIF的相关前缀,在通过soapcpp2.exe生成相关源文件之后,查看源代码可发现在代码上对这些改动的体现。

:gsoap-2.8.80以上已经加默认入到typemap.dat中

3 产生onvif.h

ONVIF官方文档,主要包含了函数的描述,SOAP Action,函数输入、输出接口等

Wsdl的资料在Onvif官方Wsdl文档中的ONVIF WSDL and XML Schemas Specifications一节,虽然可以全部下载为wsdl文件,但是wsdl文件中存在相互依赖的关系,并且是带有存储的依赖,所以一般最好直接使用url来产生头文件,不要下载下来。

官方2.0文档:   http://www.onvif.org/onvif/ver20/util/operationIndex.html 
官方wsdl文档: http://www.onvif.org/Documents/Specifications.aspx

<1> 使用URL产生onvif.h:

wsdl2h.exe -o onvif.h -c -s -t typemap.dat http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl

<2> 使用本地文件产生onvif.h:

wsdl2h.exe -o onvif.h -s -t typemap.dat remotediscovery.wsdl

其中-c为产生纯c代码,不然为c++代码;-s为不使用STL库,-t为typemap.dat的标识

4 根据onvif来产生相关源文件

soapcpp2.exe onvif.h -x -I [your path]\gsoap\import -I [your path]\gsoap

由于客户端主动发起Probe探针,所以只需产生客户端C代码,其中-x表示不产生xml文件,-I表示指定import路径。特别注意需要指定两个gsoap的两个目录,当中有产生源文件时所需的相关文件,如果不添加目录,也可在使用下面命令

soapcpp2.exe -x onvif.h

然后按照提示找到缺少的文件后添加到目录下。

产生文件如下

5 测试代码

客户端测试代码

#include <iostream>
#include "wsdd.nsmap"
#include "soapH.h"
using namespace std;
int main()
{
    struct soap *soap;
    struct wsdd__ProbeType req;
    struct __wsdd__ProbeMatches resp;
    struct wsdd__ScopesType sScope;
    struct SOAP_ENV__Header header;
    int count = 0;
    int result = 0; 

    char guid_string[100];

     soap = soap_new(); 
    if(soap==NULL)
    {
        return -1;
    }
 
    soap_set_namespaces(soap, namespaces); 

    soap->recv_timeout = 5;		//超过5秒钟没有数据就退出
    soap_default_SOAP_ENV__Header(soap, &header);
 
    header.wsa__MessageID = guid_string;
    header.wsa__To= "urn:schemas-xmlsoap-org:ws:2005:04:discovery";
    header.wsa__Action= "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe";
    soap->header = &header;

    soap_default_wsdd__ScopesType(soap, &sScope);
    sScope.__item = "";
    soap_default_wsdd__ProbeType(soap, &req);
    req.Scopes = &sScope;
    req.Types = "";

    result = soap_send___wsdd__Probe(soap, "soap.udp://239.255.255.250:3702", NULL, &req);

    do{
         result = soap_recv___wsdd__ProbeMatches(soap, &resp); 
         if (soap->error) 
         { 
             cout<<"soap error:"<<soap->error<<soap_faultcode(soap)<<"---"<<soap_faultstring(soap)<<endl; 
             result = soap->error; 
             break;
         } 
         else
         {
            cout<<"========================================="<<endl;
 
            cout<<"Match size:"<<resp.wsdd__ProbeMatches->__sizeProbeMatch<<endl;
            cout<<"xsd-unsignedInt:"<<resp.wsdd__ProbeMatches->ProbeMatch->MetadataVersion<<endl;
            cout<<"scopes item:"<<resp.wsdd__ProbeMatches->ProbeMatch->Scopes->__item<<endl;
            //cout<<"scopes matchby:"<<resp.wsdd__ProbeMatches->ProbeMatch->Scopes->MatchBy<<endl;
            cout<<"QName:"<<resp.wsdd__ProbeMatches->ProbeMatch->Types<<endl;
            cout<<"xsd:string:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.Address<<endl;
            cout<<"xsd:QName:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.PortType<<endl;
            cout<<"wsa:ServiceNameType:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.ServiceName<<endl;
            cout<<"sequence of elements:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.__size<<endl;
            cout<<"xsd:anyType:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.__anyAttribute<<endl;
            cout<<"endpoint any:"<<resp.wsdd__ProbeMatches->ProbeMatch->wsa__EndpointReference.__any<<endl;
            cout<<"wsdd:UriListType:"<<resp.wsdd__ProbeMatches->ProbeMatch->XAddrs<<endl;
         }
     }while(1);

    soap_destroy(soap); // remove deserialized class instances (C++ only) 
    soap_end(soap);		// clean up and remove deserialized data
    soap_done(soap);

    return result;
} 

6 结果

启动onvif的测试工具,点开Discovery,点击Discovery Device

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值