Onvif工作整理总结(二)问题及解决汇总

Onvif工作整理总结(二)问题及解决汇总

  • Onvif问题及解决汇总
      • 错误码
      • 其他问题
      • 参考文档

Onvif问题及解决汇总

错误码

目前见过的错误码返回值为:-1,4,8,12,401,其实错误码的值并不重要,当我们发现有错误时,应该使用调试工具ONVIF Device test tool等去模拟发送和接收,并查看接收到的错误信息的打印,最为可靠;

  1. 在组播搜索设备、单播搜索设备等功能中,使用函数 :

soap_recv___wsdd__ProbeMatches(struct soap *soap, struct __wsdd__ProbeMatches *_param_1)

返回值 soap->error = -1;

解决方法:接收失败,多为IPC离线、网络问题、可以尝试查看设备是否在线,或者调大接收超时时间来调试。

  1. 获取设备能力(GetCapabilities)时,使用函数:

SOAP_FMAC5 int SOAP_FMAC6 soap_call___tds__GetCapabilities(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _tds__GetCapabilities *tds__GetCapabilities, struct _tds__GetCapabilitiesResponse *tds__GetCapabilitiesResponse)

返回值 soap->error = 8;

解决方法:遇到IPC无法识别的命名空间,不使用初始化头文件函数1,使用初始化头文件函数2(平时用函数1,当判断到return == 8,就调用函数2,再重新获取能力即可);
初始化头文件函数1:bool OnvifInitHeader(struct soap* pSoap)

struct SOAP_ENV__Header *header = NULL;
if(NULL == pSoap) return false;
header = (struct SOAP_ENV__Header *)OnvifSoapMalloc(pSoap, sizeof(struct SOAP_ENV__Header));
soap_default_SOAP_ENV__Header(pSoap, header);
header->wsa__MessageID = (char*)soap_wsa_rand_uuid(pSoap);
header->wsa__To        = (char*)OnvifSoapMalloc(pSoap, strlen(SOAP_TO) + 1);
header->wsa__Action    = (char*)OnvifSoapMalloc(pSoap, strlen(SOAP_ACTION) + 1);
strcpy(header->wsa__To, SOAP_TO);
strcpy(header->wsa__Action, SOAP_ACTION);
pSoap->header = header;
return true;

初始化头文件函数2:bool OnvifInitHeader2(struct soap* pSoap)

struct SOAP_ENV__Header *header = NULL;
header = (struct SOAP_ENV__Header *)OnvifSoapMalloc(pSoap, sizeof(struct SOAP_ENV__Header));
soap_default_SOAP_ENV__Header(pSoap, header);
pSoap->header = header;
return true;
  1. 获取简介(GetProfiles)时,使用函数:

SOAP_FMAC5 int SOAP_FMAC6 soap_call___trt__GetProfiles(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _trt__GetProfiles *trt__GetProfiles, struct _trt__GetProfilesResponse *trt__GetProfilesResponse)

返回值 soap->error = 4;

***解决方法:遇到了两次返回值为4的情况,第一次是修改文件stdsoap2.cpp下函数soap_s2byte(struct soap soap, const char s, char p);注释掉代码中注释的部分,错误就消失了;第二次是因为IPC主码流或其他码流中含有gsoap不识别的音视频编码格式,例如H265,我使用的是第一版的onvif协议,gsoap也不能正确解析H265,所以报错,有兴趣的朋友可以参考这位大神的做法:Linux下onvif客户端获取h265 IPC摄像头的RTSP地址,或者直接修改摄像头视频编码格式为H264即可;

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;
}
  1. 鉴权时报错:

返回值 soap->error = 401;

解决方法:摄像头用户名或者密码出错,输入正确的用户名密码就可以了。

返回值 soap->error = 12;

解决方法:摄像头设置了输入密码多次错误后,针对指定IP锁死禁止访问的机制,可以在程序里加密码判断来避免其多次错误的情况,或者修改IPC的安全配置中的选项,以下是海康摄像头的配置界面:
Onvif工作整理总结(二)问题及解决汇总_第1张图片

其他问题

  1. 拿到IPC后在确认了其具备onvif功能后,要确保它开启onvif功能,并且存在onvif用户;以下是海康摄像头为例:

Onvif工作整理总结(二)问题及解决汇总_第2张图片

  1. 在我尝试组播搜索的时候只有同一网段的IPC能够返回信息值到我的程序,其他IPC即使在一个局域网内,但是不是同一网段的IPC,都不会返回消息;但是使用工具ONVIF Device test tool组播搜索的时候又能找到不同网段的IPC;这个问题尚未解决,希望有大神提供思路;

  2. 一开始我使用了一个单例模式,创建了一个soap* 的成员变量,就一直使用这个成员变量作为参数去调用各种功能;但是这样随着运行时间增加,调用功能函数次数增多会出现内存泄漏!!!。最后还是使用创建后就销毁的策略来解决了内存泄漏的问题;

参考文档

  1. 关于onvif对接海康设备出现soap->error=4的问题
  2. Linux下onvif客户端获取h265 IPC摄像头的RTSP地址

你可能感兴趣的:(onvif工作总结)