带有鉴权字段的onvif框架代码生成

时间:2024-03-20 07:31:06
 一、生成带有鉴权字段的onvif框架代码
       之前已在ubuntu12.04LTS上安装了gSOAP2.8.19. 注意使用此流程生成完全框架的时候需要gsoap已经安装在了linux系统中否则会出现一些奇怪的问题,故再使用的时候需先安装gsoap
       新建一个文件夹,从gSOAP2.8.19的安装目录中找到typemap.dat将其与从http://www.onvif.org/Documents/Specifications.aspx官网下载的WSDL文件放在同一文件夹中。另外查看所使用的typemap.dat是否包含如下部分代码
#   ONVIF recommended prefixes
tds = "http://www.onvif.org/ver10/device/wsdl"
tev = "http://www.onvif.org/ver10/events/wsdl"
tls = "http://www.onvif.org/ver10/display/wsdl"
tmd = "http://www.onvif.org/ver10/deviceIO/wsdl"
timg        = "http://www.onvif.org/ver20/imaging/wsdl"
trt = "http://www.onvif.org/ver10/media/wsdl"
tptz        = "http://www.onvif.org/ver20/ptz/wsdl"
trv = "http://www.onvif.org/ver10/receiver/wsdl"
trc = "http://www.onvif.org/ver10/recording/wsdl"
tse = "http://www.onvif.org/ver10/search/wsdl"
trp = "http://www.onvif.org/ver10/replay/wsdl"
tan = "http://www.onvif.org/ver20/analytics/wsdl"
tad = "http://www.onvif.org/ver10/analyticsdevice/wsdl"
tdn = "http://www.onvif.org/ver10/network/wsdl"
tt  = "http://www.onvif.org/ver10/schema"
#   OASIS recommended prefixes
wsnt        = "http://docs.oasis-open.org/wsn/b-2"
wsntw       = "http://docs.oasis-open.org/wsn/bw-2"
wsrfbf      = "http://docs.oasis-open.org/wsrf/bf-2"
wsrfr       = "http://docs.oasis-open.org/wsrf/r-2"
wsrfrw  = "http://docs.oasis-open.org/wsrf/rw-2"
wstop       = "http://docs.oasis-open.org/wsn/t-1"
#   WS-Discovery 1.0 remapping
wsdd10__HelloType           = | wsdd__HelloType
wsdd10__ByeType                     = | wsdd__ByeType
wsdd10__ProbeType           = | wsdd__ProbeType
wsdd10__ProbeMatchesType    = | wsdd__ProbeMatchesType
wsdd10__ProbeMatchType              = | wsdd__ProbeMatchType
wsdd10__ResolveType         = | wsdd__ResolveType
wsdd10__ResolveMatchesType  = | wsdd__ResolveMatchesType
wsdd10__ResolveMatchType    = | wsdd__ResolveMatchType
#   SOAP-ENV mapping
SOAP_ENV__Envelope  = struct SOAP_ENV__Envelope { struct SOAP_ENV__Header *SOAP_ENV__Header; _XML SOAP_ENV__Body; }; | struct SOAP_ENV__Envelope
SOAP_ENV__Header    = | struct SOAP_ENV__Header
SOAP_ENV__Fault             = | struct SOAP_ENV__Fault
SOAP_ENV__Detail    = | struct SOAP_ENV__Detail
SOAP_ENV__Code              = | struct SOAP_ENV__Code
SOAP_ENV__Subcode   = | struct SOAP_ENV__Subcode
SOAP_ENV__Reason    = | struct SOAP_ENV__Reason
   如果不包含则需要将此部分复制到所使用的typemap.dat文件中。具体参照下面链接
       使用如下命令生成onvif.h文件 此处如果系统中已经安装了gsoap工具在wsdl2h这个名令可直接使用
wsdl2h  -c  -s  -t  ./typemap.dat  -o  onvif.h  accesscontrol.wsdl accessrules.wsdl actionengine.wsdl advancedsecurity.wsdl  analyticsdevice.wsdl  analytics.wsdl credential.wsdl deviceio.wsdl devicemgmt.wsdl display.wsdl doorcontrol.wsdl  event.wsdl  imaging.wsdl  media.wsdl ptz.wsdl  receiver.wsdl recording.wsdl   remotediscovery.wsdl  replay.wsdl  schedule.wsdl   search.wsdl   thermal.wsdl  
      使用此命令去生成onvif.h中间也是需要从网络下载东西的,所以在生成的时候虚拟机的网络要保持畅通如果网络出现问题会出现如下问题。此时只需要将网络修复即可

       另外从官网下载的WSDL其中在devicemgmt.wsdl需要作如下修改,下图中的红线部分是devicemgmt.wsdl中指定onvif.xsd的地方,需要注意的就是这里,此处使用的是绝对路径,所以需要将你onvif.xsd的绝对路径填在此处。在编译过程中出现的某某路径找不到 onvif.xsd文件均依照此办法修改即可。
在这个过程中会有许多需要修改的地方,基本都是由于onvi.xsd的路径不对,所以建议大家先修改然后再一次性使用上述命令,另外在运行此命令的时候中间会出现卡顿的情况,如果卡的时间较长建议直接ctrl+c掉重新运行。
带有鉴权字段的onvif框架代码生成
此过程需等待的时间较长……不过最终还是生成了onvif.h
带有鉴权字段的onvif框架代码生成
       上一步生成的onvif.h文件中没有打开wsse.h, 导致最后生成代码中SOAP_ENV__Header 结构体中缺少定义 wsse__Security数据段,无法进行鉴权命令。必须修改如下:   
    1.在生成的onvif.h中添加 #import “wsse.h"  (切记不要写成 #include "wsse.h")-----大概在onvif.h文件的96行附近
    2.soapcpp2 -c onvif.h -x -I import的绝对路径 -I gsoap的绝对路径
  在我的虚拟机上使用如下命令
soapcpp2 -c onvif.h -x -I  /usr/gsoap_2.8.19/gsoap-2.8/gsoap/import -I /usr/gsoap_2.8.19/gsoap-2.8/gsoap
期间发现如下错误需:打开gsoap_2.8.17\gsoap-2.8\gsoap\import 路径下的wsa5.h, 将277行的SOAP_ENV__Fault结构体注释掉(改成其他名字亦可)
 我采用了将其注掉。
带有鉴权字段的onvif框架代码生成
至此框架生成成功
带有鉴权字段的onvif框架代码生成

框架编译说明:

(1) gsoap鉴权用到的文件: dom.c wsseapi.c smdevp.c mecevp.c threads.c wsaapi.c,还有对应的头文件。这些文件一般在\gsoap-2.8\gsoap\plugin\,把这些文件单独拷贝到编译目录中,无关的文件一概不拷贝。

(2) makefile中必须添加编译开关-DWITH_DOM -DWITH_OPENSSL

(3) wsse系列函数必须链接标准的openssl库:libssl.so、libcrypto.so。可以下载OPENSSL1.0.0的软件包编译。

二、OPENSSL1.0.0安装编译成动态链接库:

参考博文链接;http://blog.csdn.net/david_xtd/article/details/7057443

                http://blog.sina.com.cn/s/blog_79ba23780101s3h5.html-----重点

安装包:http://pan.baidu.com/s/1c1NiwRA  密码:cmlz

    1.  ./config no-asm shared --prefix=/usr/local/Openssl_ARM_SO

        此步骤中的 no-asm的使用是由于嵌入式arm设备有些不支持使用汇编进行加速。

     2.修改makefile

                     


  1. 62 #CC= gcc
  2.  63 CC = arm-unknown-linux-gnu-gcc
  3.  64 #CFLAG= -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall
  4.  65 CFLAG= -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DOPENSSL_NO_KRB5 -DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall
  5.  66 DEPFLAG= -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_STORE
  6.  67 PEX_LIBS=
  7.  68 EX_LIBS= -ldl
  8.  69 EXE_EXT=
  9.  70 ARFLAGS=
  10.  71 #AR= ar $(ARFLAGS) r
  11.  72 AR = arm-unknown-linux-gnu-ar $(ARFLAGS) r
  12.  73 RANLIB = arm-unknown-linux-gnu-ranlib
  13.  74 #RANLIB= /usr/bin/ranlib
  14.  75 #NM= nm
  15.  76 NM = arm-unknown-linux-gnu-nm
  16.  77 PERL= /usr/bin/perl
  17.  78 TAR= tar
  18.  79 TARFLAGS= --no-recursion
  19.  80 MAKEDEPPROG= gcc
  20.  81 LIBDIR=lib
3.make  -----进行编译
4.make install  ----安装
完成后在/usr/loacl/Openssl_ARM_SO 目录下的lib下就有编译好的openssl的动态库
如果需要编译静态库的时候把步骤1中的shared去掉即可




prefix 是安装目录,openssldir 是配置文件目录,另外建议安装两次(这样就能既声称.a静态库,同时也生成.so静态库),shared 作用是生成动态连接库。

  1. tar -zxf openssl-1.0.0e.tar.gz
  2. cd openssl-1.0.0e/
  3. ./config --prefix=/usr/local --openssldir=/usr/local/ssl
  4. make && make install
  5. ./config shared --prefix=/usr/local --openssldir=/usr/local/ssl
  6. make clean
  7. make && make install  
  8. 环境变量添加:

4 编译的说明

(1) gsoap鉴权用到的文件: dom.c wsseapi.c smdevp.c mecevp.c threads.c wsaapi.c,还有对应的头文件。这些文件一般在\gsoap-2.8\gsoap\plugin\,把这些文件单独拷贝到编译目录中,无关的文件一概不拷贝。

(2) makefile中必须添加编译开关-DWITH_DOM -DWITH_OPENSSL

(3) wsse系列函数必须链接标准的openssl库:libssl.so、libcrypto.so。可以下载OPENSSL1.0.0的软件包编译。

 

   ( 4 ) 在PC上使用gcc实现的时候仅仅是在 程序链接的时候将libssl.so、libcrypto.so库链接进去,并且还需将dom.c wsseapi.c smdevp.c mecevp.c threads.c wsaapi.c,还有对应的头文件包含在工程之中。不过此处需特别注意的是在编译 wsaapi.c的时候需要使用-DWITH_DOM -DWITH_OPENSSL这个编译开关。建议在编译的时候直接将这两个编译选项直接加上即可。以免出错。期间出现的一些错误请自行处理。

  (5) 在onvif设备鉴权的时候server端的函数调用:

            soap_wsse_get_Username(struct soap *soap)-------------用于获取传输的用户名。此处需先进行获取用户名,然后与自身IPC所有的用户名进行比较,如果存在此用户名,则可进行下一步的鉴权,如果此用户名不存在的话即可直接返回错误,确定鉴权失败。

             soap_wsse_verify_Password(struct soap *soap, const char *password)在上个函数获取到用户名后,就从IPC自己的用户管理部分获取用户的密码,填入此处的passwd进行校验。如果校验成功就返回SOAP_OK,表示鉴权成功,否则鉴权失败,

            另外还有一个用于判断有效期的函数,soap_wsse_verify_Timestamp。 用于判断是否在有效期内,由于小编这边的IPC与NVR的时间同步并没有使用onvif进行时间同步,所以此有效期的判断我这里没有进行深入研究。

            对于client方面的鉴权,参考网上大多数的例子即可。




我发现在服务器上存在libssl.so.0.9.8,路径如下:/work/mv_pro_5.0/montavista/pro/devkit/arm/v5t_le/target/usr/lib。

/montavista/pro/devkit/arm/v5t_le/target/usr/include/openssl,这里是对应的头文件。


经过尝试,该库是x86平台的,不能在分机上运行。最后找到交叉编译后的库文件: libssl.so.1.0.0, libcrypto.so.1.0.0, 分别替换到上述路径。另外必须使用openssl1.0.0软件包中的头文件替换到上述路径中,不然的话就会造成链接的库是1.0.0版本,而程序编译时的数据结构还是0.9.8版本的,引起程序运行时指错误死机,一般报告释放指针错误。

必须在交叉工具链目录下替换openssl1.0.0头文件的原因:因为openssl工具包中的文件头部都是# include <openssl/opensslconf.h>之类。<>包含的文件首先到系统搜索路径下寻找,然后才到当前目录寻找,因此即使把这些头文件拷贝到编译目录下也无用。

(4) 链接ssl、crypto库文件时,必须提供索引文件libssl.so--> libssl.so.1.0.0 libcrypto.so--> libcrypto.so.1.0.0否则就会自动链接到服务器上的x86版本库文件,在分机上不能运行。

5 运行makefile, 生成searchOnvif。


对于生成的两个动态链接库的引用顺序:-lssl -lcrypto,如果为-lcrypto –lssl,编译时会出现错误











伸手党福利:
2.8.17 完整框架:http://download.csdn.net/detail/no_pao_spite/9857291