# BilysenOnvif **Repository Path**: jerry_qt_admin/bilysen_onvif ## Basic Information - **Project Name**: BilysenOnvif - **Description**: onvif 协议的学习和代码 - **Primary Language**: C - **License**: LGPL-2.1 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2024-06-06 - **Last Updated**: 2024-06-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # BilysenOnvif # 介绍 onvif 协议的学习和代码 主要是跟着这个 csdn 专栏进行学习和开发 https://blog.csdn.net/benkaoya/category_6924052.html?spm=1001.2014.3001.5482 [Onvif 网络接口规范网址](https://www.onvif.org/ch/profiles/specifications/) # 安装教程 没有必要重复造轮子,onvif 的 web service 是通过 soap 的方式。涉及SOAP、HTTP、XML,RPC等概念和模块。自己手写明显不是一个好的方法。针对 c/c++ 有 gsoap 工具生成。java 语言有 Apache CXF 工具。python 还有对应的 onvif 库进行调用。在这里只使用 gsoap 工具生成。 [gsoap 开源版最新下载地址](http://sourceforge.net/projects/gsoap2) ## 编译 gsoap 步骤 ```bash # gsoap 工具放在 tool 里面 unzip gsoap_2.8.134.zip ./configure -prefix $(pwd)/install make # make 之后可能会出现的编译错误 # stdsoap2.h:903:11: fatal error: openssl/bio.h: No such file or directory # 903 | # include sudo apt-get install libssl-dev # stdsoap2.h:956:11: fatal error: zlib.h: No such file or directory # 956 | # include sudo apt-get install zlib1g-dev make install # 确认wsdl2h soapcpp2 是否编译成功 find -name wsdl2h find -name soapcpp2 ``` ## gsoap 生成 onvif 框架步骤 1. 根据这个网址 https://www.genivia.com/resources.html 里面的 How_do_I_use_gSOAP_with_the_ONVIF_specifications? 章节来判断是否需要修改 typemap.dat 2. 生成头文件和源代码 ``` bash cd ./tool/gsoap-2.8/gsoap # Command 'wsdl2h' not found, but can be installed with: sudo apt install gsoap # 生成 onvif.h wsdl2h -P -x -c -s -t ./typemap.dat -o mysamples/onvif.h https://www.onvif.org/ver10/network/wsdl/remotediscovery.wsdl https://www.onvif.org/ver10/device/wsdl/devicemgmt.wsdl https://www.onvif.org/ver10/media/wsdl/media.wsdl # 因为鉴权认证的需要,要在 onvif.h 加上 #import "wsse.h" # 根据 onvif.h 生成源代码 soapcpp2 -2 -c -x -I import:custom -d mysamples/ mysamples/onvif.h # wsa5.h(280): *WARNING*: Duplicate declaration of 'SOAP_ENV__Fault' (already declared at line 268) # 在 onvif.h 文件中 #import "wsdd10.h" // wsdd10.h中又#import "wsa.h" #import "wsa5.h" // wsa.h和wsa5.h两个文件重复定义了int SOAP_ENV__Fault # 修改import\wsa5.h文件,将int SOAP_ENV__Fault修改为int SOAP_ENV__Fault_alex 重新 soapcpp2 生成即可 # 剩下的待验证 # 拷贝其他有用的代码 cp stdsoap2.c stdsoap2.h plugin/wsaapi.c plugin/wsaapi.h custom/duration.c custom/duration.h mysamples/ # mysamples\stdsoap2.h 中有命名空间 namespaces 变量的定义声明 # 需要在 mysamples\stdsoap2.h 中 #include "wsdd.nsmap" # 删除 onvif.h 文件,以及多个 .nsmap 文件, 仅仅保留 wsdd.nsmap 即可 # 需要将其他文件一并移到代码框架的文件夹下(工作中暂时只遇到这些),下面路径需要对照实际路径 cp ../gsoap-2.8/gsoap/stdsoap2.c ./ cp ../gsoap-2.8/gsoap/stdsoap2.h ./ cp ../gsoap-2.8/gsoap/custom/duration.c ./ cp ../gsoap-2.8/gsoap/custom/duration.h ./ cp ../gsoap-2.8/gsoap/plugin/wsddapi.c ./ cp ../gsoap-2.8/gsoap/plugin/wsddapi.h ./ cp ../gsoap-2.8/gsoap/plugin/wsaapi.h ./ cp ../gsoap-2.8/gsoap/plugin/wsaapi.c ./ cp ../gsoap-2.8/gsoap/plugin/threads.h ./ cp ../gsoap-2.8/gsoap/plugin/threads.c ./ ``` 3. 写一个 makefile 进行编译,以下是编译过程中可能出现的错误 ``` c // 在 stdsoap2.h 里面 SOAP_FMAC1 int SOAP_FMAC2 soap_element_empty(struct soap*, const char *tag, int id, const char *type); // 在 soapC.c 里面 soap_element_empty(soap, tag); // #编译之后会出现 error too few arguments to function ‘soap_element_empty’ 手动删除编译函数 (后面确认是版本不一致导致的, 看下面版本不一致问题) stdsoap2.h:694:25: error: unknown type name ‘locale_t’ #define SOAP_LOCALE_T locale_t stdsoap2.h:3003:3: note: in expansion of macro ‘SOAP_LOCALE_T’ SOAP_LOCALE_T c_locale; /* if this does not compile, use ./configure --enable-xlocale or compile with -DWITH_INCLUDE_XLOCALE_H, or use -DWITH_NO_C_LOCALE to disable locale support */ // CFLAGS 中添加编译选项 -DWITH_NO_C_LOCALE soapStub.h:48:3: error: #error "GSOAP VERSION 20891 MISMATCH IN GENERATED CODE VERSUS LIBRARY CODE: PLEASE REINSTALL PACKAGE" # error "GSOAP VERSION 20891 MISMATCH IN GENERATED CODE VERSUS LIBRARY CODE: PLEASE REINSTALL PACKAGE" ^ make: *** [: soapServerLib.o] Error 1 //经查找,发现系统自带了一个 wsdl2 不知道之前是否自己操作失误了。而且这两个 wsdl2 的版本还不一样。而 stdsoap2.h 这个文件是从 2.8.134 那里复制过来的。其他 onvif 的 web service 是 2.8.9 生成的,所以导致版本不一样。只能确定好版本重新生成。 wsddapi.c: In function ‘soap_wsdd_Hello’: wsddapi.c:577:6: error: ‘struct wsdd__HelloType’ has no member named ‘wsa5__EndpointReference’ req.wsa5__EndpointReference.Address = (char*)EndpointReference; // 在 soapStub.h 中注释掉 #define SOAP_WSA_2005 duration.c:216:32: error: conflicting types for ‘soap_in_xsd__duration’ SOAP_FMAC3 LONG64 * SOAP_FMAC4 soap_in_xsd__duration(struct soap *soap, const char *tag, LONG64 *a, const char *type) // 在 typemap.dat 中添加这个语句 xsd__duration = #import "custom/duration.h" | xsd__duration 重新生成代码 ./soapServerLib.o: In function `soap_serve___trt__GetVideoSourceConfigurations': soapServerLib.c:(.text+0x544138): undefined reference to `__trt__GetVideoSourceConfigurations' ./soapServerLib.o: In function `soap_serve___trt__GetVideoEncoderConfigurations': soapServerLib.c:(.text+0x544414): undefined reference to `__trt__GetVideoEncoderConfigurations' ./soapServerLib.o: In function `soap_serve___trt__GetAudioSourceConfigurations': soapServerLib.c:(.text+0x5446f0): undefined reference to `__trt__GetAudioSourceConfigurations' // 引用了 soapStub.h 里面函数,实现需要本人去完成。 // 出现 multiple definition of `__wsdd__Resolve' 等,重复定义了,找到并删除多余的或者注释掉 // undefined reference to `SOAP_ENV__Fault_alex' 把相关的 SOAP_ENV__Fault_alex 这个注释掉,回旋镖啊 ``` # mysample 文件夹 表示能够正常编译的 onvif 代码框架,目前已经将上述的步骤出现的问题解决,可以来当模版