onvif开发之二:discovery

自己调试OK的客户端discovery功能,discovery code,编译的时候,请修改脚本中的Path为自己gSoap所在的Path。

先从remotediscovery.wsdl解析入手吧。可以参考此网页WSDL实例解析 和 一个完整的WSDL文档及各标签详解

1、命名空间

这个非常重要,直接导致是否可以调用到web server的功能函数。

targetNamespace="http://www.onvif.org/ver10/network/wsdl",采用的命空间。

2、结构体定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
< wsdl:types >
         < xs:schema  targetNamespace = "http://www.onvif.org/ver10/network/wsdl"  xmlns:d = "http://schemas.xmlsoap.org/ws/2005/04/discovery"  elementFormDefault = "qualified" >
             < xs:import  namespace = "http://schemas.xmlsoap.org/ws/2005/04/discovery"  schemaLocation = "http://schemas.xmlsoap.org/ws/2005/04/discovery/ws-discovery.xsd" />
             <!--  Message Request/Responses elements  -->
             <!--===============================-->
             < xs:element  name = "Hello"  type = "d:HelloType" />
             < xs:element  name = "HelloResponse"  type = "d:ResolveType" />
             < xs:element  name = "Probe"  type = "d:ProbeType" />
             < xs:element  name = "ProbeResponse"  type = "d:ProbeMatchesType" />
             < xs:element  name = "Bye"  type = "d:ByeType" />
             < xs:element  name = "ByeResponse"  type = "d:ResolveType" />
             <!--===============================-->
         </ xs:schema >
     </ wsdl:types >

schemaLocation="http://schemas.xmlsoap.org/ws/2005/04/discovery/ws-discovery.xsd"/,进入/ws-discovery.xsd可以看到

1
2
3
4
5
6
7
8
< xs:complexType  name = "ProbeType" >
< xs:sequence >
< xs:element  ref = "tns:Types"  minOccurs = "0" />
< xs:element  ref = "tns:Scopes"  minOccurs = "0" />
< xs:any  namespace = "##other"  processContents = "lax"  minOccurs = "0"  maxOccurs = "unbounded" />
</ xs:sequence >
< xs:anyAttribute  namespace = "##other"  processContents = "lax" />
</xs:complexType

code中对应的为,命名由 <xs:element name="Probe" type="d:ProbeType"/> 中的 type="d:ProbeType"而来

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef SOAP_TYPE_d__ProbeType
#define SOAP_TYPE_d__ProbeType (290)
/* d:ProbeType */
struct  d__ProbeType
{
     char  **Types;    /* optional element of type xsd:QName */
     struct  d__ScopesType *Scopes;    /* optional element of type d:ScopesType */
     int  __size;  /* sequence of elements <-any> */
     char  **__any;
     char  *__anyAttribute;    /* optional attribute of type xsd:anyType */
};
#endif
3、参数
1
2
3
4
</ wsdl:message >
< wsdl:message  name = "ProbeRequest" >
     < wsdl:part  name = "parameters"  element = "dn:Probe" />
</ wsdl:message >

<wsdl:part name="parameters" element="dn:Probe"/> 表明使用的是 <xs:element name="Probe" type="d:ProbeType"/>,也即为struct d__ProbeType。


4、函数体

1
2
3
4
5
6
< wsdl:portType  name = "DiscoveryLookupPort" >
         < wsdl:operation  name = "Probe" >
             < wsdl:input  message = "dn:ProbeRequest"  dn:Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe" />
             < wsdl:output  message = "dn:ProbeResponse"  dn:Action = "http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches" />
         </ wsdl:operation >
     </ wsdl:portType >

这个 dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe" 望文生义是关于Probe()的具体不知道什么意义,也没有找到此页面。知道的同学请告知。

客户端: 

SOAP_FMAC5 int SOAP_FMAC6 soap_call___d__Probe(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct d__ProbeType *d__Probe, struct d__ProbeMatchesType *d__ProbeMatches)

soap_call___d__Probe(和soap_serve___d__Probe交互可以调用用web server的Probe功能。

服务端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
soap_serve --> soap_serve_request --> soap_serve___d__Probe --> sever_probe
*/
int  main( int  argc,  char  **argv)
{
     int  m, s;
     struct  soap add_soap;
     soap_init(&add_soap);
     soap_set_namespaces(&add_soap, namespaces);
 
     if  (argc < 2) {
         printf ( "usage: %s <server_port> \n" , argv[0]);
         exit (1);
     else  {
         m = soap_bind(&add_soap, NULL,  atoi (argv[1]), 100);
         if  (m < 0) {
             soap_print_fault(&add_soap, stderr);
             exit (-1);
         }
         fprintf (stderr,  "Socket connection successful: master socket = %d\n" , m);
         for  (;;) {
             s = soap_accept(&add_soap);
             if  (s < 0) {
                 soap_print_fault(&add_soap, stderr);
                 exit (-1);
             }
             fprintf (stderr,  "Socket connection successful: slave socket = %d\n" , s);
             soap_serve(&add_soap);
             soap_end(&add_soap);
         }
     }
     return  0;
}
 
SOAP_FMAC5  int  SOAP_FMAC6 soap_serve( struct  soap *soap)
{
#ifndef WITH_FASTCGI
     unsigned  int  k = soap->max_keep_alive;
#endif
     do
     {
#ifndef WITH_FASTCGI
         if  (soap->max_keep_alive > 0 && !--k)
             soap->keep_alive = 0;
#endif
         if  (soap_begin_serve(soap))
         {    if  (soap->error >= SOAP_STOP)
                 continue ;
             return  soap->error;
         }
         if  (soap_serve_request(soap) || (soap->fserveloop && soap->fserveloop(soap)))
         {
#ifdef WITH_FASTCGI
             soap_send_fault(soap);
#else
             return  soap_send_fault(soap);
#endif
         }
 
#ifdef WITH_FASTCGI
         soap_destroy(soap);
         soap_end(soap);
     while  (1);
#else
     while  (soap->keep_alive);
#endif
     return  SOAP_OK;
}
 
SOAP_FMAC5  int  SOAP_FMAC6 soap_serve_request( struct  soap *soap)
{
     soap_peek_element(soap);
     if  (!soap_match_tag(soap, soap->tag,  "SOAP-ENV:Fault" ))
         return  soap_serve_SOAP_ENV__Fault(soap);
     if  (!soap_match_tag(soap, soap->tag,  "d:Hello" ))
         return  soap_serve___d__Hello(soap);
     if  (!soap_match_tag(soap, soap->tag,  "d:Bye" ))
         return  soap_serve___d__Bye(soap);
     if  (!soap_match_tag(soap, soap->tag,  "d:Probe" ))
         return  soap_serve___d__Probe(soap);
......
}
   
soap_serve___d__Probe
{
     sever_probe();
}

5、绑定

这个就是wsdl和soap的结合了。前面的理解没问题的话,这部分就不用关心了。

调通了discovery,只是一个良好的开端。后续还有一堆事情要解决。待续。

6、其他

​最后采用的代码是soap_send___wsdd__Probe/soap_recv___wsdd__ProbeMatches,空间不同而已。换用soap_send___wsdd__Probe的时候,出了一个小BUG:设定的timeout 似乎对soap_recv___wsdd__ProbeMatches无效。经排查对比,发现是gsoap版本的差异。

while (result == SOAP_OK)
{
//gsoap2.8.17 block, gsoap2.8.1.10 timeout enable
result = soap_recv___wsdd__ProbeMatches(psoap, &res);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值