linux下gsoap编译onvif,实现discovery探测设备

1.首先下载gsoap工具。我目前使用的gsoap 2.8

2.解压到某个目录,编译安装

./configure
make 
make install

3.新建一个工程目录,cd进去,用wsdl2h生成onvif.h文件

wsdl2h -o onvif.h -s -t ./typemap.dat http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl http://www.onvif.org/onvif/ver10/display.wsdl http://www.onvif.org/onvif/ver10/deviceio.wsdl http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl http://www.onvif.org/onvif/ver10/receiver.wsdl http://www.onvif.org/onvif/ver10/recording.wsdl http://www.onvif.org/onvif/ver10/search.wsdl http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/replay.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl http://www.onvif.org/ver10/actionengine.wsdl http://www.onvif.org/ver10/pacs/accesscontrol.wsdl http://www.onvif.org/ver10/pacs/doorcontrol.wsdl

其中,-c为产生纯c代码,不然为c++代码;-s为不使用STL库;因为习惯用C++了,所有就不加-c了。

注意:http的url之间是空格。


4.在onvif.h中,添加

#import "wsse.h" 
打开文件gsoap_2.8/gsoap-2.8/gsoap/import/ wsa5.h
将277行int SOAP_ENV__Fault修改为int SOAP_ENV__Fault_alex


5.在自定义的工程目录中,根据onvif.h产生onvif代码

soapcpp2 -cpp onvif.h -x -I../gsoap-2.8 -I../gsoap-2.8/gsoap -I../gsoap-2.8/gsoap/import/
其中-x表示不产生xml文件,-I表示指定import路径。


6.从gsoap源码目录,拷贝一些需要的文件到工程目录,可参考的文件有,可供参考(只需看*.cpp,*.c,*.h文件)

linux下gsoap编译onvif,实现discovery探测设备_第1张图片



7.测试一个简单的discovery例子程序,main.cpp(网上找的)

#include 
#include "RemoteDiscoveryBinding.nsmap"
#include "soapH.h"

using namespace std;
int main()
{
printf("onvif\n");
    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:"<error<error; 
             break;
         } 
         else
         {
            cout<<"========================================="<__sizeProbeMatch<ProbeMatch->MetadataVersion<ProbeMatch->Scopes->__item<ProbeMatch->Scopes->MatchBy<ProbeMatch->Types<ProbeMatch->wsa__EndpointReference.Address<ProbeMatch->wsa__EndpointReference.PortType<ProbeMatch->wsa__EndpointReference.ServiceName<ProbeMatch->wsa__EndpointReference.__size<ProbeMatch->wsa__EndpointReference.__anyAttribute<ProbeMatch->wsa__EndpointReference.__any<ProbeMatch->XAddrs<

8.编译链接

g++ -ggdb -I./ -c -o main.o main.cpp -I./ 
 g++ -ggdb -I./ -c -o duration.o duration.c
 g++ -ggdb -I./ -c -o soapC.o soapC.cpp 
 g++ -ggdb -I./ -c -o soapClient.o soapClient.cpp
 g++ -ggdb -I./ -c -o stdsoap2.o stdsoap2.cpp 
 g++ -ggdb -I./ ./*.o -o main

时间关系,就不写makefile了,谁写了makefile可以留言分享一下,感激!


9.执行./main发现断错误了,于是gdb调试了以下,原来是一个数组没有初始化,可能是新版本的问题,也可能是我不懂用把,直接注释掉整个if就OK了

gdb main
r

15671	        soap->labbuf[soap->labidx > 0 ? soap->labidx - 1 : 0] = '\0';
(gdb) bt
#0  0x086d2e97 in soap_QName2s (soap=0x88bf008, s=0x86de812 "")
    at stdsoap2.cpp:15671
#1  0x085417ad in soap_out_wsdd__ProbeType (soap=0x88bf008, 
    tag=0x86f4c4d "wsdd:Probe", id=0, a=0xbffff5b8, type=0x86e9f85 "")
    at soapC.cpp:354751
#2  0x08653ecc in soap_out_PointerTowsdd__ProbeType (soap=0x88bf008, 
    tag=0x86f4c4d "wsdd:Probe", id=0, a=0xbffff54c, type=0x86e9f85 "")
    at soapC.cpp:429797
#3  0x0853d805 in soap_out___wsdd__Probe (soap=0x88bf008, 
    tag=0x86dea18 "-wsdd:Probe", id=-2, a=0xbffff54c, type=0x86de940 "")
    at soapC.cpp:353485
#4  0x0853da6a in soap_put___wsdd__Probe (soap=0x88bf008, a=0xbffff54c, 
    tag=0x86dea18 "-wsdd:Probe", type=0x86de940 "") at soapC.cpp:353541
#5  0x0804b1f3 in soap_send___wsdd__Probe (soap=0x88bf008, 
    soap_endpoint=0x86de814 "soap.udp://239.255.255.250:3702", 
    soap_action=0x86de9dc "http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01/Probe", wsdd__Probe=0xbffff5b8) at soapClient.cpp:208
#6  0x0804a268 in main () at main.cpp:41
(gdb) 

找到stdsoap2.cpp的第15671行,把原来的if(...)改成if(0);


10. 执行

./main












你可能感兴趣的:(onvif,协议类)