记一次onvif协议开发遇到的异常处理

在一次对接海康onvif协议设备时,调用getprotfiles 返回错误码4(SOAP_TYPE),意思是 :An XML Schema type mismatch 。
显然问题出在海康设备返回的数据格式不对,唯一能做的就是找到出错的数据,然后看看能不能修改一下soap源代码,让其流程继续进行下去。
采用非常暴力的排查方法,将返回SOAP_TYPE的地方全部打上断点,然后运行程序。后来定位到是在stdsoap2.cpp的一个转换成long的函数中,源码如下:
点击查看代码
#ifndef PALM_2
SOAP_FMAC1
int
SOAP_FMAC2
soap_s2long(struct soap *soap, const char *s, long *p)
{ if (s)
  { char *r;
#ifndef WITH_NOIO
#ifndef WITH_LEAN
    soap_reset_errno;
#endif
#endif
    *p = soap_strtol(s, &r, 10);
    if (s == r || *r
#ifndef WITH_NOIO
#ifndef WITH_LEAN
     || soap_errno == SOAP_ERANGE
#endif
#endif
    )
      soap->error = SOAP_TYPE;
  }
  return soap->error;
}
#endif

当s="H265"时,soap_strtol处理失败,返回SOAP_TYPE。

于是将soap_s2long函数的代码修改一下,让其不返回错误,问题暂时得到解决。

点击查看代码
#ifndef PALM_2
SOAP_FMAC1
int
SOAP_FMAC2
soap_s2long(struct soap *soap, const char *s, long *p)
{ if (s)
  { char *r;
#ifndef WITH_NOIO
#ifndef WITH_LEAN
    soap_reset_errno;
#endif
#endif
    long res = soap_strtol(s, &r, 10);
    if( 0 == res)
    {
        *p = 0;
        return soap->error;
    }
    *p = soap_strtol(s, &r, 10);
    if (s == r || *r
#ifndef WITH_NOIO
#ifndef WITH_LEAN
     || soap_errno == SOAP_ERANGE
#endif
#endif
    )
      soap->error = SOAP_TYPE;
  }
  return soap->error;
}
#endif

后来,用onvif device test tool 重新对 该流媒体进行了测试分析,发现其出错的地方是在

tt:EncodingH265</tt:Encoding> 这一处。至于为什么soap库要将其解析为long还不得而知。

点击查看代码
<tt:VideoEncoderConfiguration token="VideoEncoderToken_2">
          <tt:Name>VideoEncoder_2</tt:Name>
          <tt:UseCount>1</tt:UseCount>
          <tt:Encoding>H265</tt:Encoding>
          <tt:Resolution>
            <tt:Width>352</tt:Width>
            <tt:Height>288</tt:Height>
          </tt:Resolution>
          <tt:Quality>3.000000</tt:Quality>
          <tt:RateControl>
            <tt:FrameRateLimit>8</tt:FrameRateLimit>
            <tt:EncodingInterval>1</tt:EncodingInterval>
            <tt:BitrateLimit>128</tt:BitrateLimit>
          </tt:RateControl>
          <tt:Multicast>
            <tt:Address>
              <tt:Type>IPv4</tt:Type>
              <tt:IPv4Address>239.255.2.15</tt:IPv4Address>
            </tt:Address>
            <tt:Port>8866</tt:Port>
            <tt:TTL>128</tt:TTL>
            <tt:AutoStart>false</tt:AutoStart>
          </tt:Multicast>
          <tt:SessionTimeout>PT5S</tt:SessionTimeout>
        </tt:VideoEncoderConfiguration>
posted @ 2021-10-09 11:45  罗曼骑士  阅读(636)  评论(0编辑  收藏  举报