初学onvif协议,环境是在linux下,使用gsoap生成了代码框架,经过修修改改,终于能编译通过了,但使用GetCapabilities,想获取海康IPC的Media(或其它设备能力)地址时,没有任何报错,但Response->Capabilities->Media == NULL,代码如下。
#include
#include
#include <string.h>
#include <assert.h>
#include "soapH.h"
#include "stdsoap2.h"
#include "soapStub.h"
#include "wsseapi.h"
//#include "wsdd.nsmap" //命名空间
static struct soap* ONVIF_Initsoap(struct SOAP_ENV__Header *header, const char *was_To, const char *was_Action, int timeout)
{
struct soap *soap = NULL; // soap环境变量
unsigned char macaddr[6];
char _HwId[1024];
unsigned int Flagrand;
soap = soap_new();
if(soap == NULL)
{
printf("[%d]soap = NULL\n", __LINE__);
return NULL;
}
soap_set_namespaces(soap, namespaces); // 设置soap的namespaces,即设置命名空间
// 设置超时(超过指定时间没有数据就退出)
if(timeout > 0)
{
soap->recv_timeout = timeout;
soap->send_timeout = timeout;
soap->connect_timeout = timeout;
}
else
{
//Maximum waittime : 20s
soap->recv_timeout = 20;
soap->send_timeout = 20;
soap->connect_timeout = 20;
}
header = (struct SOAP_ENV__Header *)soap_malloc(soap, sizeof(struct SOAP_ENV__Header));
soap_default_SOAP_ENV__Header(soap, header);
//Create SessionID randomly,生成uuid(windows下叫guid,linux下叫uuid),格式为urn:uuid:8-4-4-4-12,由系统随机产生
srand((int)time(0));
Flagrand = rand()%9000 + 8888;
macaddr[0] = 0x1;
macaddr[1] = 0x2;
macaddr[2] = 0x3;
macaddr[3] = 0x4;
macaddr[4] = 0x5;
macaddr[5] = 0x6;
sprintf(_HwId, "urn:uuid:%ud68a-1dd2-11b2-a105-%02X%02X%02X%02X%02X%02X", Flagrand, macaddr[0], macaddr[1], macaddr[2],macaddr[3],macaddr[4],macaddr[5]);
header->wsa__MessageID = (char *)malloc(100);
memset(header->wsa__MessageID, 0, 100);
strncpy(header->wsa__MessageID, _HwId, strlen(_HwId)); //wsa__MessageID存放的是uuid
if(was_Action != NULL)
{
header->wsa__Action = (char*)malloc(1024);
memset(header->wsa__Action, '\0', 1024);
strncpy(header->wsa__Action, was_Action, 1024); //
}
if(was_To != NULL)
{
header->wsa__To = (char *)malloc(1024);
memset(header->wsa__To, '\0', 1024);
strncpy(header->wsa__To, was_To, 1024);//"urn:schemas-xmlsoap-org:ws:2005:04:discovery";
}
soap->header = header;
return soap;
}
//释放函数
void ONVIF_soap_delete(struct soap *soap)
{
soap_destroy(soap); // remove deserialized class instances (C++ only)
soap_end(soap); // Clean up deserialized data (except class instances) and temporary data
soap_free(soap); // Reset and deallocate the context created with soap_new or soap_copy
}
//鉴权
static int ONVIF_SetAuthInfo(struct soap *soap, const char *username, const char *password)
{
int result = 0;
if((NULL != username) || (NULL != password)){
soap_wsse_add_UsernameTokenDigest(soap, NULL, username, password);
}else{
printf("un etAuth\n");
result = -1;
}
return result;
}
int main(int argc,char *argv[])
{
int ret = 0;
char sercer_addr[] = "http://192.168.3.105/onvif/device_service"; //设备搜索得到的地址
struct SOAP_ENV__Header header;
struct soap* soap = ONVIF_Initsoap(&header, NULL, NULL, 5);
struct _tds__GetCapabilities *req;
struct _tds__GetCapabilitiesResponse *Response;
if(NULL == (req = (struct _tds__GetCapabilities *)calloc(1,sizeof(struct _tds__GetCapabilities))))
{
printf("calloc is error \n");
ret = -1;
return ret;
}else{
req->__sizeCategory = 1;
req->Category = (enum tt_x00a0__CapabilityCategory *)soap_malloc(soap, sizeof(int));
*(req->Category) = (enum tt_x00a0__CapabilityCategory)5; //5表示:tt_x00a0__CapabilityCategory__Media
ONVIF_SetAuthInfo(soap,"test","12345678."); //鉴权,输入摄像头的用户名、密码
ret = soap_call___tds__GetCapabilities(soap, sercer_addr, NULL,req, Response);
if(soap->error){
ret = -1;
printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
return ret;
}else{
if(NULL != Response->Capabilities)
{
if (Response->Capabilities->Media != NULL){
if (Response->Capabilities->Media->XAddr != NULL){
printf(" media_addr: %s \n", Response->Capabilities->Media->XAddr);
}
}
printf("soap error: %d, %s, %s\n", soap->error, *soap_faultcode(soap), *soap_faultstring(soap));
}
}
}
if(NULL != req)
{
free(req);
req = NULL;
}
ONVIF_soap_delete(soap);
return ret;
}
代码运行的效果就是soap->error == 0,但Response->Capabilities->Media == NULL,所以我追看了gsoap的DEBUG日志,发现发送和接收都没有问题,返回的HTTP协议内容完整,XML中也可以看到我需要的值。但问题是无法正确解析收到的信息,具体报错如下:
Tags 'tt:Media' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:Media'
也就是说应该是因为没有解析正确,所以导致了Response->Capabilities->Media没有被填充,关键log如下:
Push OK ('wsadis' matches 'wsa' in namespace table)
stdsoap2.c(14669): malloc(58) = 0x7ffff7742980
stdsoap2.c(14752): malloc(256) = 0x7ffff7742a00
stdsoap2.c(3596): malloc(36) = 0x7ffff7742b40
Push namespace binding (level=0,index=19) 'wsnt'='http://docs.oasis-open.org/wsn/b-2'
Push OK ('wsnt' matches 'wsnt' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff7742ba0
stdsoap2.c(14752): malloc(256) = 0x7ffff7742c20
stdsoap2.c(3583): malloc(37) = 0x7ffff7742d60
stdsoap2.c(3596): malloc(35) = 0x7ffff7742dc0
Push namespace binding (level=0,index=4) 'wsa'='http://www.w3.org/2005/08/addressing'
Push OK ('wsa' matches 'wsa' in namespace table)
stdsoap2.c(14669): malloc(59) = 0x7ffff7742e20
stdsoap2.c(14752): malloc(256) = 0x7ffff7742ea0
stdsoap2.c(3596): malloc(37) = 0x7ffff7742fe0
Push namespace binding (level=0,index=20) 'wstop'='http://docs.oasis-open.org/wsn/t-1'
Push OK ('wstop' matches 'wstop' in namespace table)
stdsoap2.c(14669): malloc(61) = 0x7ffff7743040
stdsoap2.c(14752): malloc(256) = 0x7ffff77430c0
stdsoap2.c(3596): malloc(39) = 0x7ffff7743200
Push namespace binding (level=0,index=37) 'wsrf-bf'='http://docs.oasis-open.org/wsrf/bf-2'
Push OK ('wsrf-bf' matches 'wsrf-bf' in namespace table)
stdsoap2.c(14669): malloc(59) = 0x7ffff7743260
stdsoap2.c(14752): malloc(256) = 0x7ffff77432e0
stdsoap2.c(3596): malloc(37) = 0x7ffff7743420
Push namespace binding (level=0,index=36) 'wsntw'='http://docs.oasis-open.org/wsn/bw-2'
Push OK ('wsntw' matches 'wsntw' in namespace table)
stdsoap2.c(14669): malloc(61) = 0x7ffff7743480
stdsoap2.c(14752): malloc(256) = 0x7ffff7743500
stdsoap2.c(3596): malloc(39) = 0x7ffff7743640
Push namespace binding (level=0,index=35) 'wsrf-rw'='http://docs.oasis-open.org/wsrf/rw-2'
Push OK ('wsrf-rw' matches 'wsrf-rw' in namespace table)
stdsoap2.c(14669): malloc(58) = 0x7ffff77436a0
stdsoap2.c(14752): malloc(256) = 0x7ffff7743720
stdsoap2.c(3596): malloc(36) = 0x7ffff7743860
Push namespace binding (level=0,index=34) 'wsaw'='http://www.w3.org/2006/05/addressing/wsdl'
Push OK ('wsaw' matches 'wsaw' in namespace table)
stdsoap2.c(14669): malloc(60) = 0x7ffff77438c0
stdsoap2.c(14752): malloc(256) = 0x7ffff7743940
stdsoap2.c(3596): malloc(38) = 0x7ffff7743a80
Push namespace binding (level=0,index=33) 'wsrf-r'='http://docs.oasis-open.org/wsrf/r-2'
Push OK ('wsrf-r' matches 'wsrf-r' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff7743ae0
stdsoap2.c(14752): malloc(256) = 0x7ffff7743b60
stdsoap2.c(3596): malloc(35) = 0x7ffff7743ca0
Push namespace binding (level=0,index=32) 'trc'='http://www.onvif.org/ver10/recording/wsdl'
Push OK ('trc' matches 'trc' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff7743d00
stdsoap2.c(14752): malloc(256) = 0x7ffff7743d80
stdsoap2.c(3596): malloc(35) = 0x7ffff7743ec0
Push namespace binding (level=0,index=31) 'tse'='http://www.onvif.org/ver10/search/wsdl'
Push OK ('tse' matches 'tse' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff7743f20
stdsoap2.c(14752): malloc(256) = 0x7ffff7743fa0
stdsoap2.c(3596): malloc(35) = 0x7ffff77440e0
Push namespace binding (level=0,index=30) 'trp'='http://www.onvif.org/ver10/replay/wsdl'
Push OK ('trp' matches 'trp' in namespace table)
stdsoap2.c(14669): malloc(60) = 0x7ffff7744140
stdsoap2.c(14752): malloc(256) = 0x7ffff77441c0
stdsoap2.c(3596): malloc(38) = 0x7ffff7744300
Push namespace binding (level=0,index=29) 'tnshik'='http://www.hikvision.com/2011/event/topics'
Push OK ('tnshik' matches 'tnshik' in namespace table)
stdsoap2.c(14669): malloc(60) = 0x7ffff7744360
stdsoap2.c(14752): malloc(256) = 0x7ffff77443e0
stdsoap2.c(3596): malloc(38) = 0x7ffff7744520
Push namespace binding (level=0,index=28) 'hikwsd'='http://www.onvifext.com/onvif/ext/ver10/wsdl'
Push OK ('hikwsd' matches 'hikwsd' in namespace table)
stdsoap2.c(14669): malloc(60) = 0x7ffff7744580
stdsoap2.c(14752): malloc(256) = 0x7ffff7744600
stdsoap2.c(3596): malloc(38) = 0x7ffff7744740
Push namespace binding (level=0,index=27) 'hikxsd'='http://www.onvifext.com/onvif/ext/ver10/schema'
Push OK ('hikxsd' matches 'hikxsd' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff77447a0
stdsoap2.c(14752): malloc(256) = 0x7ffff7744820
stdsoap2.c(3596): malloc(35) = 0x7ffff7744960
Push namespace binding (level=0,index=26) 'tas'='http://www.onvif.org/ver10/advancedsecurity/wsdl'
Push OK ('tas' matches 'tas' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff77449c0
stdsoap2.c(14752): malloc(256) = 0x7ffff7744a40
stdsoap2.c(3596): malloc(35) = 0x7ffff7744b80
Push namespace binding (level=0,index=24) 'tr2'='http://www.onvif.org/ver20/media/wsdl'
Push OK ('tr2' matches 'tr2' in namespace table)
stdsoap2.c(14669): malloc(57) = 0x7ffff7744be0
stdsoap2.c(14752): malloc(256) = 0x7ffff7744c60
stdsoap2.c(3596): malloc(35) = 0x7ffff7744da0
Push namespace binding (level=0,index=25) 'axt'='http://www.onvif.org/ver20/analytics'
Push OK ('axt' matches 'axt' in namespace table)
Tags and (default) namespaces match: 'env:Envelope' 'SOAP-ENV:Envelope'
Begin tag found (level=1) 'env:Envelope'='SOAP-ENV:Envelope'
stdsoap2.c(12510): malloc(40) = 0x7ffff7744e00
Tags and (default) namespaces match: 'env:Body' 'SOAP-ENV:Body'
Begin tag found (level=2) 'env:Body'='SOAP-ENV:Body'
Tags and (default) namespaces match: 'tds:GetCapabilitiesResponse' 'tds:GetCapabilitiesResponse'
Begin tag found (level=3) 'tds:GetCapabilitiesResponse'='tds:GetCapabilitiesResponse'
Enter id='' type=644 location=0x7f157482b710 size=8
Tags and (default) namespaces match: 'tds:Capabilities' 'tds:Capabilities'
Begin tag found (level=4) 'tds:Capabilities'='tds:Capabilities'
Reverting to last element 'tds:Capabilities' (level=3)
Tags and (default) namespaces match: 'tds:Capabilities' 'tds:Capabilities'
Begin tag found (level=4) 'tds:Capabilities'='tds:Capabilities'
Enter id='' type=645 location=(nil) size=56
stdsoap2.c(10431): malloc(80) = 0x7ffff7744e60
Unexpected element 'tt:Media' in input at level = 4 body = 1)
Tags 'tt:Media' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:Media'
Ignoring XML content at level=5
End tag found (level=5) 'tt:Media'=''
Unexpected element 'tt:Extension' in input at level = 4 body = 1)
Tags 'tt:Extension' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:Extension'
Ignoring XML content at level=5
End tag found (level=5) 'tt:Extension'=''
End tag found (level=4) 'tds:Capabilities'='tds:Capabilities'
End tag found (level=3) 'tds:GetCapabilitiesResponse'='tds:GetCapabilitiesResponse'
End tag found (level=2) 'env:Body'='SOAP-ENV:Body'
End tag found (level=1) 'env:Envelope'='SOAP-ENV:Envelope'
End of receive message ok
Resolving forwarded refs
Resolution phase
Resolution done
Free namespace stack
想请教有没有遇到过该情况的,应该如何解决。
命名空间不匹配
看下你的命名空间是不是类似下边这种
static const struct Namespace namespaces[] = {
{ "SOAP-ENV", "http://www.w3.org/2003/05/soap-envelope", "http://schemas.xmlsoap.org/soap/envelope/", NULL },
{ "SOAP-ENC", "http://www.w3.org/2003/05/soap-encoding", "http://schemas.xmlsoap.org/soap/encoding/", NULL },
{ "xsi", "http://www.w3.org/2001/XMLSchema-instance", "http://www.w3.org/*/XMLSchema-instance", NULL },
{ "xsd", "http://www.w3.org/2001/XMLSchema", "http://www.w3.org/*/XMLSchema", NULL },
{ "chan", "http://schemas.microsoft.com/ws/2005/02/duplex", NULL, NULL },
{ "wsa5", "http://www.w3.org/2005/08/addressing", "http://schemas.xmlsoap.org/ws/2004/08/addressing", NULL },
{ "c14n", "http://www.w3.org/2001/10/xml-exc-c14n#", NULL, NULL },
{ "ds", "http://www.w3.org/2000/09/xmldsig#", NULL, NULL },
{ "saml1", "urn:oasis:names:tc:SAML:1.0:assertion", NULL, NULL },
{ "saml2", "urn:oasis:names:tc:SAML:2.0:assertion", NULL, NULL },
{ "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", NULL, NULL },
{ "xenc", "http://www.w3.org/2001/04/xmlenc#", NULL, NULL },
{ "wsc", "http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512", "http://schemas.xmlsoap.org/ws/2005/02/sc", NULL },
{ "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd", NULL },
{ "ns2", "http://www.onvif.org/ver10/pacs", NULL, NULL },
{ "ns5", "http://www.onvif.org/ver20/analytics/humanface", NULL, NULL },
{ "ns6", "http://www.onvif.org/ver20/analytics/humanbody", NULL, NULL },
{ "xmime", "http://tempuri.org/xmime.xsd", NULL, NULL },
{ "xop", "http://www.w3.org/2004/08/xop/include", NULL, NULL },
{ "tt", "http://www.onvif.org/ver10/schema", NULL, NULL },
{ "wsrfbf", "http://docs.oasis-open.org/wsrf/bf-2", NULL, NULL },
{ "wstop", "http://docs.oasis-open.org/wsn/t-1", NULL, NULL },
{ "wsrfr", "http://docs.oasis-open.org/wsrf/r-2", NULL, NULL },
{ "ns1", "http://www.onvif.org/ver10/accesscontrol/wsdl", NULL, NULL },
{ "ns10", "http://www.onvif.org/ver20/media/wsdl", NULL, NULL },
{ "ns11", "http://www.onvif.org/ver10/provisioning/wsdl", NULL, NULL },
{ "ns12", "http://www.onvif.org/ver10/schedule/wsdl", NULL, NULL },
{ "ns13", "http://www.onvif.org/ver10/thermal/wsdl", NULL, NULL },
{ "ns14", "http://www.onvif.org/ver10/uplink/wsdl", NULL, NULL },
{ "ns3", "http://www.onvif.org/ver10/accessrules/wsdl", NULL, NULL },
{ "ns4", "http://www.onvif.org/ver10/actionengine/wsdl", NULL, NULL },
{ "ns7", "http://www.onvif.org/ver10/authenticationbehavior/wsdl", NULL, NULL },
{ "ns8", "http://www.onvif.org/ver10/credential/wsdl", NULL, NULL },
{ "ns9", "http://www.onvif.org/ver10/doorcontrol/wsdl", NULL, NULL },
{ "tan", "http://www.onvif.org/ver20/analytics/wsdl", NULL, NULL },
{ "tas", "http://www.onvif.org/ver10/advancedsecurity/wsdl", NULL, NULL },
{ "tds", "http://www.onvif.org/ver10/device/wsdl", NULL, NULL },
{ "tev", "http://www.onvif.org/ver10/events/wsdl", NULL, NULL },
{ "wsnt", "http://docs.oasis-open.org/wsn/b-2", NULL, NULL },
{ "timg", "http://www.onvif.org/ver20/imaging/wsdl", NULL, NULL },
{ "tls", "http://www.onvif.org/ver10/display/wsdl", NULL, NULL },
{ "tmd", "http://www.onvif.org/ver10/deviceIO/wsdl", NULL, NULL },
{ "tptz", "http://www.onvif.org/ver20/ptz/wsdl", NULL, NULL },
{ "trc", "http://www.onvif.org/ver10/recording/wsdl", NULL, NULL },
{ "trp", "http://www.onvif.org/ver10/replay/wsdl", NULL, NULL },
{ "trt", "http://www.onvif.org/ver10/media/wsdl", NULL, NULL },
{ "trv", "http://www.onvif.org/ver10/receiver/wsdl", NULL, NULL },
{ "tse", "http://www.onvif.org/ver10/search/wsdl", NULL, NULL },
{ NULL, NULL, NULL, NULL}
};
Tags 'tt:Media' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:Media'
标记“tt:Media”和“SOAP-ENV:”匹配,但命名空间不同
IGNORING元素“tt:Media”
两种可能
1.你调用了一个自定义或是第三方的类,所以要引用第三方的类的空间或自己的
2.你想调用的是System.Media,那么,你不可以这样调用,因为Media是命名空间,不是类,这个命名空间下应该有三个类,明白没?
System.Media.SoundPlayer sp = new System.Media.SoundPlayer();