摄像头型号:DH-IPC-HDW130S-0600B
MAC:90:02:A9:3D:1A:63
默认IP: 192.168.16.108, 修改使用IP:192.168.0.108
默认用户名密码;admin:admin
软件里面查看版本信息如下:
设备类型 IPC-HDW4105S
软件版本 2.400.0000.0.R, build : 2013-12-31
WEB版本 3.2.4.161826
ONVIF版本 2.3
序列号 TGC4AW158W00019
有意思的一点是摄像头标签上的型号是HDW130s,但是固件中的设备类型却是HDW4105S,不一致的哦。
-------------------------------------------------------------------
问题1:我的分机发出probe命令,但是没有收到大华IPC应答,无法发现 。
问题分析:OnvifTest软件可以正确发现大华IPC,抓包比对OnvifTest报文和我的报文,发现SOAP-ENV不同。百度后明白原因如下:
我使用的gsoap版本生成 RemoteDiscoveryBinding.nsmap,内容是有版本区别的。
//SOAP 1.1版本
{"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope",
NULL},
{"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.org/*/soap-encoding",
NULL}, //1.1
//SOAP 1.2版本
{"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}, //1.2
1.1版本的可以发现海康IPC,1.2版本才能发现大华IPC。使用1.2版本内容,收到大华Probe应答,解析成功。
-------------------------------------------------------------------
问题2:我的分机发出GetCapabilities命令,无应答。
问题分析:
还是对比OnvifTest软件和分机发出的GetCapabilities命令,发现主要是域名空间不同。
这是使用ONVIF TEST软件发送的GetCapabilities
POST /onvif/device_service HTTP/1.1
Host: 192.168.0.108
Content-Type: application/soap+xml; charset=utf-8
Content-Length: 335
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
一共使用了4个命名,
xmlns s="http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
xmlns="http://www.onvif.org/ver10/device/wsdl">
而gsoap生成的RemoteDiscoveryBinding.nsmap,完整的命令空间如下,密密麻麻好多啊!
SOAP_NMAC struct Namespace namespaces[] ={
{"SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/", "http://www.w3.org/*/soap-envelope",
NULL},
{"SOAP-ENC", "http://schemas.xmlsoap.org/soap/encoding/", "http://www.w3.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},
{"wsa", "http://schemas.xmlsoap.org/ws/2004/08/addressing", NULL, NULL},
{"wsdd", "http://schemas.xmlsoap.org/ws/2005/04/discovery", NULL, 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},
{"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://schemas.xmlsoap.org/ws/2005/02/sc", NULL, NULL},
{"ds", "http://www.w3.org/2000/09/xmldsig#", NULL, 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},
{"xmime", "http://www.w3.org/2005/05/xmlmime", NULL, NULL},
{"ns5", "http://www.w3.org/2004/08/xop/include", NULL, NULL},
{"ns6", "http://docs.oasis-open.org/wsrf/bf-2", NULL, NULL},
{"ns3", "http://www.onvif.org/ver10/schema", NULL, NULL},
{"ns4", "http://docs.oasis-open.org/wsn/b-2", NULL, NULL},
{"ns7", "http://docs.oasis-open.org/wsn/t-1", NULL, NULL},
{"wsdd10", "http://tempuri.org/wsdd10.xsd", NULL, NULL},
{"ns1", "http://www.onvif.org/ver10/network/wsdl", NULL, NULL},
{"ns2", "http://www.onvif.org/ver10/device/wsdl", NULL, NULL},
{"ns8", "http://www.onvif.org/ver10/media/wsdl", NULL, NULL},
{NULL, NULL, NULL, NULL}
};
尝试只保留上述4个命名空间,就收到了大华IPC应答。由此确定是分机中的命令空间太多了,大华摄像头不支持某些命名空间,直接无视了,却不会发出任何错误应答。有了这个教训,后面的过程都是小心翼翼的试验只添加命令报文中使用的命名空间,这样就不会出现无应答错误了。最终各种命令汇总后的必须命名空间如下:
xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope" ‘
xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
xmlns:wsdd="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:ns1="http://www.onvif.org/ver10/network/wsdl"
xmlns:ns2="http://www.onvif.org/ver10/device/wsdl"
xmlns:ns3="http://www.onvif.org/ver10/schema"
xmlns:ns8="http://www.onvif.org/ver10/media/wsdl">
------------------------------------------------------------------
问题3: 我的分机设备发出Probe命令成功,发现了大华IPC,然后发送命令GetCapabilities,收到了大华IPC应答报文,但是分机却返回error=SOAP_TYPE,导致失败。使用OnvifTest软甲测试GetCapabilities,IPC发送了同样的报文,就可以正确解析。
问题分析过程:
SOAP_TYPE: 标准解释是An XML Schema type mismatch, 到底是个什么意思我也说不出来,猜测是一些字段或域名空间关键字错误。
(1)首先怀疑报文解析过程中的每个字段项解析是否出现了错误,确定是哪个字段项错误。
方法:编译分机程序时天机编译开关-DDEBUG,这样运行分机程序会自动生成调试文件:RECV.log、SENT.log、TEST.log。打开TEST.log文件,查找error没有发现。观察报文解析过程,发现出现在这一段:
遇到Extension段中包含Extensions段,内部的Extensions段都未能识别出来,后面的log中都没有出现该段内容的解析过程。这种TelexCapabilities是海康IPC报文中没有的,在gsoap代码中也找不到该字段。由此确定是该段解析出错。
(2)确定代码中的错误位置
从GetCapabilities命令的调用关系一层层的跟踪下去,
soap_call___ns2__GetCapabilities() soapClient.c
soap_get__ns2__GetCapabilitiesResponse() 该函数执行后出现error=SOAP_TYPE
soap_in__ns2__GetCapabilitiesResponse()
soap_in_PointerTons3__Capabilities()
soap_in_ns3__Capabilities()
soap_in_PointerTons3__CapabilitiesExtension()
soap_in_ns3__CapabilitiesExtension()
soap_in_PointerTons3__CapabilitiesExtension2()
soap_in_ns3__CapabilitiesExtension2()
最后的CapabilitiesExtension2()返回error=SOAP_TYPE,通过添加打印信息确定是if (soap_in_byte(soap, "-any", a->__any, "xsd:byte"))出现失败。 仔细观察soap_in_byte()函数,内部调用 stdsoap2.c soap_s2byte()函数,目的是把输入字符串转换成10进制的整数。
soap_s2byte(struct soap *soap, const char *s, char *p)
{ if (s)
{ long n;
char *r;
n = soap_strtol(s, &r, 10);
if (s == r || *r || n < -128 || n > 127)
{
soap->error = SOAP_TYPE;
}
*p = (char)n;
}
return soap->error;
}
soap_s2byte这个函数调用soap_strtol进行转换,s是输入字符串,p指向转换后的单字节。但是对于s=“”空字符串无法转换成功,引起s==r成立,导致错误返回SOAP_TYPE。 看起来好像是gsoap的一个bug。修改方法是去除s==r的判断条件,避免报告错误。
if ( n < -128 || n > 127)
{
soap->error = SOAP_TYPE;
}
这样修改后就不会出现错误了,soap_call___ns2__GetCapabilities() 解析成功,TEST.log文件中也可以看到相关字段的解析了,下列内容是发现了字段,但是无法识别,予以忽略。
Tags and (default) namespaces match: 'tt:Extensions' 'ns3:Extensions'
Begin element found (level=6) 'tt:Extensions'='ns3:Extensions'
Reverting to last element 'tt:Extensions' (level=5)
Tags and (default) namespaces match: 'tt:Extensions' 'ns3:Extensions'
Begin element found (level=6) 'tt:Extensions'='ns3:Extensions'
Enter id='' type=781 loc=(nil) size=8 level=0
stdsoap2.c(7512): malloc(20) = 0x410d98
New block sequence (prev=(nil))
stdsoap2.c(2187): malloc(12) = 0x410dc8
Push block of 1 bytes (1 bytes total)
stdsoap2.c(2209): malloc(9) = 0x410df0
Enter id='' type=3 loc=0x410df8 size=1 level=0
Element content value=''
Push block of 1 bytes (2 bytes total)
stdsoap2.c(2209): malloc(9) = 0x410e18
Enter id='' type=3 loc=0x410e20 size=1 level=0
Element content value=''
Unexpected element 'tt:TelexCapabilities' in input (level=6, 1)
Tags 'tt:TelexCapabilities' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:TelexCapabilities'
Unexpected element 'tt:XAddr' in input (level=7, 1)
Tags 'tt:XAddr' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:XAddr'
End element found (level=8) 'tt:XAddr'=''
Unexpected element 'tt:TimeOSDSupport' in input (level=7, 1)
Tags 'tt:TimeOSDSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:TimeOSDSupport'
End element found (level=8) 'tt:TimeOSDSupport'=''
Unexpected element 'tt:TitleOSDSupport' in input (level=7, 1)
Tags 'tt:TitleOSDSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:TitleOSDSupport'
End element found (level=8) 'tt:TitleOSDSupport'=''
Unexpected element 'tt:PTZ3DZoomSupport' in input (level=7, 1)
Tags 'tt:PTZ3DZoomSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:PTZ3DZoomSupport'
End element found (level=8) 'tt:PTZ3DZoomSupport'=''
Unexpected element 'tt:PTZAuxSwitchSupport' in input (level=7, 1)
Tags 'tt:PTZAuxSwitchSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:PTZAuxSwitchSupport'
End element found (level=8) 'tt:PTZAuxSwitchSupport'=''
Unexpected element 'tt:MotionDetectorSupport' in input (level=7, 1)
Tags 'tt:MotionDetectorSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:MotionDetectorSupport'
End element found (level=8) 'tt:MotionDetectorSupport'=''
Unexpected element 'tt:TamperDetectorSupport' in input (level=7, 1)
Tags 'tt:TamperDetectorSupport' and 'SOAP-ENV:' match but namespaces differ
IGNORING element 'tt:TamperDetectorSupport'
End element found (level=8) 'tt:TamperDetectorSupport'=''
End element found (level=7) 'tt:TelexCapabilities'=''
Pop block
stdsoap2.c(2236): free(0x410e18)
stdsoap2.c(7512): malloc(12) = 0x410e18
Save all blocks in contiguous memory space of 1 bytes (0x410df0->0x410e18)
总结: 通过上述修改,解决了大华IPC无法使用问题,分机可以发现设备、查询设备能力、修改媒体配置、获取流媒体地址。最后,分机能通过rtsp连接摄像头,显示出了视频画面。
致谢:最近才在CSDN发现一篇博文,简直就是黑夜中指路明灯啊,一下子解决困扰我大半年的问题,太谢谢这位小兵_小白大神了!
原文:关于onvif对接海康设备出现soap->error=4的问题
http://blog.csdn.net/bing87496988/article/details/38707829