使用 gsoap c++​​ 的 Onvif 服务器 WS 发现

问题描述

我一直在努力使 ws-discovery 正常工作。我参考了@mpromonet 的代码 并使用以下选项生成了类

wsdl2h.exe -O4 -P -d -t typemap.dat -o onvif.h ./ws-discovery.wsdl ./remotediscovery.wsdl ./devicemgmt.wsdl ./search.wsdl ./replay.wsdl . /media.wsdl ./media2.wsdl

soapcpp2.exe -2 -LTS -i -x -d ./onvifgen -I./gsoap/gsoap-2.8.109/gsoap/import/;./gsoap/gsoap-2.8.109/gsoap/onvif.

我在 Onvif 设备测试工具 v20.06 中发现设备时遇到问题,但通过 Onvif 设备管理器 v2.2.250 可以实现相同的发现。设备测试工具在探测时不会发现并返回设备类型为 Not NetworkVideoTransmitter。>

任何人都可以帮忙。我附上了一个可重现的例子。 谢谢

//Devicediscovery header

#pragma once
#include "stdafx.h"
#include <vector>
#include <string>



struct wsdconf {
    wsdconf(const char* xaddr,const char* type,const char* scope = "",const char* endpoint = "",int   MetadataVersion = 1)
        : m_xaddr(xaddr),m_type(type),m_scope(scope),m_endpoint(endpoint),m_MetadataVersion(MetadataVersion),m_stop(0) {}
    std::string m_xaddr;
    std::string m_type;
    std::string m_scope;
    std::string m_endpoint;
    int         m_MetadataVersion;
    int         m_stop;
};
#define IPADDRESS "http://192.168.0.101:580/onvif/device_service"
#define TYPE "tdn:NetworkVideoTransmitter"
#define ENDPOINT "urn:uuid:18763976-7674-2925-3930-616263642534"




class CDevicediscovery
{
public:
    CDevicediscovery();
    ~CDevicediscovery();
    struct soap *m_pSoapdiscover;
    int sendHello(soap * serv);
    const std::string GetScopes();
    int Rundiscovery();
};

//Devicediscovery Implementation
#include "stdafx.h"
#include "Devicediscovery.h"



CDevicediscovery::CDevicediscovery()
{

}


CDevicediscovery::~CDevicediscovery()
{
}

int CDevicediscovery::sendHello(soaP* serv)
{
    wsdconf* conf = (wsdconf*)serv->user;

    struct soaP* soap = soap_new1(SOAP_IO_UDP);
    printf("call soap_wsdd_Hello\n");
    int res = soap_wsdd_Hello(soap,SOAP_WSDD_ADHOC,// mode
        "soap.udp://239.255.255.250:3702",// address of TS
        ENDPOINT,// message ID
        NULL,"urn:endpoint",conf->m_type.c_str(),conf->m_scope.c_str(),NULL,conf->m_xaddr.c_str(),conf->m_MetadataVersion);
    if (res != SOAP_OK)
    {
        soap_print_fault(soap,stderr);
    }
    soap_destroy(soap);
    soap_end(soap);

    return soap_wsdd_listen(serv,-1000000);
}

const std::string CDevicediscovery::GetScopes()
{
    std::vector<std::string>scopes_;
    scopes_.push_back("onvif://www.onvif.org/type/NetworkVideoTransmitter ");
    scopes_.push_back("onvif://www.onvif.org/type/video_encoder ");
    scopes_.push_back("onvif://www.onvif.org/type/audio_encoder ");
    scopes_.push_back("onvif://www.onvif.org/type/NetworkVideoTransmitter ");
    scopes_.push_back("onvif://www.onvif.org/name/OnvifExample ");
    scopes_.push_back("onvif://www.onvif.org/location/Anywhere ");
    scopes_.push_back("onvif://www.onvif.org/hardware/Somil");
    std::string sScopes = "";

    for (size_t i = 0; i < scopes_.size(); ++i)
    {
        sScopes += scopes_[i];
    }
    return sScopes;
}

int CDevicediscovery::Rundiscovery()
{
    std::string str = GetScopes();
    char *cstr = new char[str.length() + 1];
    strcpy(cstr,str.c_str());;
    if (cstr == NULL)
    {
        return 0;
    }
    wsdconf conf(IPADDRESS,TYPE,cstr,ENDPOINT);
    delete [] cstr;
    struct soaP* serv = soap_new1(SOAP_IO_UDP);
    serv->bind_flags = SO_REUSEADDR;
    serv->connect_flags = SO_broADCAST;
    if (!soap_valid_socket(soap_bind(serv,3702,1000))) {
        soap_print_fault(serv,stderr);


    }
    else {
        ip_mreq mcast;
        mcast.imr_multiaddr.s_addr = inet_addr("239.255.255.250");
        mcast.imr_interface.s_addr = htonl(INADDR_ANY);
        if (setsockopt(serv->master,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char*)&mcast,sizeof(mcast))<0) {
            std::cout << "group membership Failed:" << strerror(errno) << std::endl;

        }
        else {
            serv->user = (void*)&conf;

            sendHello(serv);
            while (!conf.m_stop) {
                soap_wsdd_listen(serv,-1000000);
            }
        }
    }

    soap_destroy(serv);
    soap_end(serv);
    return 0;
}



void wsdd_event_ProbeMatches(struct soap *soap,unsigned int InstanceId,const char *SequenceId,unsigned int MessageNumber,const char *MessageID,const char *RelatesTo,struct wsdd__ProbeMatchesType *matches)
{
}

void wsdd_event_ResolveMatches(struct soap *soap,struct wsdd__ResolveMatchType *match)
{
}

void wsdd_event_Hello(struct soap *soap,const char *EndpointReference,const char *Types,const char *Scopes,const char *MatchBy,const char *XAddrs,unsigned int MetadataVersion)
{
    printf("wsdd_event_Hello\tid=%s EndpointReference=%s Types=%s Scopes=%s XAddrs=%s\n",MessageID,EndpointReference,Types,Scopes,XAddrs);
}

void wsdd_event_Bye(struct soap *soap,unsigned int *MetadataVersion)
{
    printf("wsdd_event_Bye\tid=%s EndpointReference=%s Types=%s Scopes=%s XAddrs=%s\n",XAddrs);
}

soap_wsdd_mode wsdd_event_Resolve(struct soap *soap,const char *ReplyTo,struct wsdd__ResolveMatchType *match)
{
    wsdconf* conf = (wsdconf*)soap->user;
    printf("wsdd_event_Resolve\tid=%s replyTo=%s endpoint=%s\n",ReplyTo,EndpointReference);
    if (EndpointReference && (conf->m_endpoint == EndpointReference))
    {
        soap_wsdd_ResolveMatches(soap,"34333231-3635-3837-3930-616263646566",conf->m_endpoint.c_str(),conf->m_MetadataVersion);
    }
    return SOAP_WSDD_ADHOC;
}

soap_wsdd_mode wsdd_event_Probe(struct soap *soap,struct wsdd__ProbeMatchesType *matches)
{
    wsdconf* conf = (wsdconf*)soap->user;
    //printf("wsdd_event_Probe\tid=%s replyTo=%s types=%s scopes=%s\n",Scopes);
    soap_wsdd_init_ProbeMatches(soap,matches);
    soap_wsdd_add_ProbeMatch(soap,matches,conf->m_MetadataVersion);
    soap_wsdd_ProbeMatches(soap,matches);
    return SOAP_WSDD_MANAGED;
}

对此类的调用是从示例 MFC 对话框进行的。

UINT Rundiscovery(LPVOID pParam)
{
    COnvifdiscoveryDlg* pDlg = (COnvifdiscoveryDlg*)pParam;
    pDlg->m_objdiscover.Rundiscovery();
    return 0;
}

//OnOK
AfxBeginThread(Rundiscovery,this);

//object declaration
CDevicediscovery m_objdiscover;

当通过 Onvif 设备测试工具发现时,wsdd_event_probe 永远不会被调用。 这是一个服务器实现,所有服务都内置在一个静态链接库中。 请任何人都可以帮忙。 附注此代码是从 https://github.com/mpromonet/v4l2onvif 复制和修改的。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...