Onvif学习笔记2 - 客户端搜索与能力获取实例讲解

注:由于我实际开发中参考的代码主要来自于 博客园 DoubleLi,所以完整的源码我会给出原博主的链接,我在这篇文章里可能主要就是对设备搜索的流程和原博主没说明的地方详细解释。

设备搜索

原博主源码地址:《Onvif开发之客户端搜索篇》(http://www.cnblogs.com/lidabo/p/6604957.html)

首先,Onvif使用了 IP:239.255.255.250 / Port:3702 的组播地址。

客户端在网段内发送Probe,网段内的Onvif服务端设备在收到这个Probe之后会生成一个ProbeMatch来回复给客户端,其中包含了这个服务端设备的基本信息。
根据之前生成的Onvif框架,这个ProbeMatch对应的结构体是
struct __wsdd__ProbeMatches
在DoubleLi的博文中,主要的流程是:
1. 初始化一个soap对象。
在ONVIF_ClientDiscovery函数中,struct SOAP_ENV__Header header指的是 SOAP的Envelope元素,was_To,was_Action也是用于header中填充数据的传参。
2. ONVIF_Initsoap()
定义完上述内容后,这位博主做了这个Initsoap接口,同时他也说明了这个接口是为了后续的方便,这个方便其实是对于后面的开发的鉴权操作。在搜索这一部分暂时用不到。
在这个接口里有一段代码是用于生成uuid的,这个uuid是用来填充header->wsa_MessageID字段的。因为每次的取值都要求不一样,所以使用了部分随机数+部分定值的组合方式。uuid的生成其实有一些开源方法的实现,但是这里的使用随机数做法比较取巧。
关于为什么每次的uuid都要不同:我也不知道,但是Onvif官方的《 Application Programmers Guide 》(APG)里说明了这一条。
// Each probe should have a unique MessageID to be able to match requests and responses.
3. soap_send___wsdd__Porbe() 和 soap_recv___wsdd__ProbeMatches()
这部分也就是Probe探针的发送和接收。

完整地贴一下APG里的文本:
/* ONVIF::Discovery */
// Send WS-Discovery Probe, collect the responses and then
// process the responses.
probematch_type probematcheslist[]={};
// Send probe. See chapter 4.3.1 for details
probe = ONVIF::DiscoverySendProbe(scopes, types);
// Wait a while for responses
while (data_available_and_not_timeout(probe.net_handle))
{
// This fetch next probe match so that we can put it into the list
// See chapter 4.3.2 for details
probematch = ONVIF::DiscoveryReadResponse(probe);
// Store info about the match, first check for duplicates
if (!in_list(probematcheslist, probematch))
{
    add_to_list(probematcheslist, probematch);
}
}
// Process the responses, see chapter 5.1.3 for details.
foreach (probeMatch in probematcheslist)
{
    ONVIF::ProcessMatch(probeMatch);
}
/* ONVIF::DiscoverySendProbe */
DiscoverySendProbe(scopes, types)
{
// Each probe should have a unique MessageID to be able to match
// requests and responses. We store it in the probe place holder for later checking
probe.MessageID = "uuid:" + App.uuidGenerate();
// Build probe message, we provide
// MessageID, Types and Scopes. See SOAP trace section for how
// it actually looks like.
message = App.BuildProbeMessage(probe.MessageID, types, scopes);
// Send probe to multicast address and port according to [WS-Discovery] section 2.4
probe.net_handle = App.send_multicast("239.255.255.250", 3702, message);
return probe;
}
/* ONVIF::DiscoveryReadResponse */
DiscoveryReadResponse(probe)
{
// Read response and process it.
// We need both the body and the Header:
aProbeMatches = App.ReadProbeMatches(probe.net_handle, Header);
// Check if this is a response to the probe we sent:
if (Header.RelatesTo != probe.MessageID) {
return -1;
}
// We pick what we need from the response:
probematch.types = aProbeMatches.ProbeMatch.Types;
probematch.scopes = aProbeMatches.ProbeMatch.Scopes;
// XAddrs is a space separated list of URLs to the Device service:
probematch.xaddrs = aProbeMatches.ProbeMatch.XAddrs;
probematch.metadataversion = aProbeMatches.ProbeMatch.MetadataVersion;
probematch.address = aProbeMatches.ProbeMatch.EndpointReference.Address;
return probematch;
}

获取设备能力

上面说了,在设备搜索的时候,ONVIF_Initsoap是做成了一个接口,其实为的就是做鉴权。
所谓鉴权,其实就是把服务端设备的用户名和密码信息包含进来,并做相应的加密。 当你在使用Onvif协议对设备进行操作的时候,当然需要用户名密码了。
至于为什么要在Initsoap里面做这个工作,因为鉴权的信息是要包含在soap的header中的。

原博主源码地址:《
Onvif开发之客户端搜索篇 (http://www.cnblogs.com/lidabo/p/6604963.html)

注意 鉴权时的ONVIF_GenerateDigest()接口中使用了SHA1算法,可以调用OpenSSL开源库实现。


这篇文章和上一篇讲框架生成,写的比较水,因为东西确实都差不多的。但是很多资料基本就讲到这些内容。有关实际操作的内容,我会结合《Application Programmers Guide》详细地写,可能会拖得久一点,
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值