问题描述
我一直在努力使 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 (将#修改为@)