Android端实现Onvif IPC开发:
《Android端实现Onvif IPC开发(一)——gSoap移植NDK尝试》
《Android端实现Onvif IPC开发(二)——在Android端搭建服务器模拟Onvif IP Camera》
《Android端实现Onvif IPC开发(三)——在Android端搭建RTSP服务器(更新中...)》
《Android端实现Onvif IPC开发(四)——Android编码ColorFormat解析及常见格式直接转换(更新中...)》
《Android端实现Onvif IPC开发(五)——H264,H265硬编码及RTP分片传输(更新中...)》
阅读之前,需要说明,我在进行gSoap移植时暂时失败了,而是采用方案二,在android端通过java搭建的server去模拟IPC,达到需求(实现Android端可供Onvif检测的IPC),以下是我移植的步骤及碰到的问题,你可以尝试阅读或者直接跳转到《Android端实现Onvif IPC开发(二)——在Android端搭建服务器模拟Onvif IP Camera》,以下问题留待有时间会继续解决,尽请关注后续文章,如果你已经有解决办法请务必指点一下,不甚感激
参考文档:
一、本篇项目简介
- 大家都知道Onvif在安防领域占有牢牢领先的地位,ONVIF标准为网络视频设备之间的信息交换定义通用协议,包括装置搜寻、实时视频、音频、元数据和控制信息等,Onvif在现实中的应用,大多是嵌入式开发中使用。于是我在想,能否降Onvif协议集成到Android设备上呢,并且打包成SDK,这样的话也许很有趣,让我们来动手吧!
- Onvif协议的内容:
- ONVIF规范中设备管理和控制部分所定义的接口均以Web Services的形式提供。ONVIF规范涵盖了完全的XML及WSDL的定义。每一个支持ONVIF规范的终端设备均须提供与功能相应的Web Service。服务端与客户端的数据交互采用SOAP协议
- 音视频流则通过RTP/RTSP进行
- Onvif协议模板的生成可以通过gSoap去自动生成,SOAP协议是基于XML的,需要通过他生成的.c和.h去集成到我们的项目中
- 了解一些基本概念:
- xml:可扩展标记语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言
- http:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议
- soap:简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML(标准通用标记语言下的一个子集)的协议,它被设计成在WEB上交换结构化的和固化的信息
- WS-discovery:你在预先不知道目标服务的情况下,可以动态的探测可用的服务并调用
- wsdl:网络服务描述语言是Web Service的描述语言,它包含一系列描述某个web service的定义。这里可以通俗的理解为协议定义。
二、环境搭建
-
我的开发环境是Ubuntu 16.04 LTS 内存 8G I5 4核
-
gSoap下载地址:http://www.cs.fsu.edu/~engelen/soap.html,我下载的版本是2.8.66
-
下载好解压到工程目录ipc_project
$:./configure $:make $:make install 安装完成后执行:wsdl2h或者soapcpp2查看gSOAP是否已经安装成功 然后需要安装以下基本库: sudu apt install libssl-dev sudo apt-get install cmake sudo apt-get install build-essential sudo apt-get install libgtk2.0-dev liblib2.0-dev sudo apt-get install checkinstall 将wsa5.h的SOAP_ENV__Fault改名,因为其它地方也存在这个结构体,随意改,不冲突即可 修改typemap.dat,在 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
-
此处可对应查看以下工程的指令含义
$:wsdl2h -help Usage: wsdl2h [-a] [-b] [-c|-c++|-c++11] [-D] [-d] [-e] [-f] [-g] [-h] [-I path] [-i] [-j] [-k] [-l] [-m] [-M] [-N name] [-n name] [-O1|-O2|-O3] [-P|-p] [-q name] [-R] [-r proxyhost[:port[:uid:pwd]]] [-r:userid:passwd] [-s] [-Sname] [-t typemapfile] [-U] [-u] [-V] [-v] [-w] [-W] [-x] [-y] [-z#] [-_] [-o outfile.h] infile.wsdl infile.xsd http://www... ... -a generate indexed struct names for local elements with anonymous types -b bi-directional operations (duplex ops) added to serve one-way responses -c generate C source code -c++ generate C++ source code (default) -c++11 generate C++11 source code -d use DOM to populate xs:any, xs:anyType, and xs:anyAttribute -D make attribute members with default values optional with pointers -e don't qualify enum names -f generate flat C++ class hierarchy -g generate global top-level element declarations -h display help info -Ipath use path to find files -i don't import (advanced option) -j don't generate SOAP_ENV__Header and SOAP_ENV__Detail definitions -k don't generate SOAP_ENV__Header mustUnderstand qualifiers -l display license information -m use xsd.h module to import primitive types -M suppress error "must understand element with wsdl:required='true'" -Nname use name for service prefixes to produce a service for each binding -nname use name as the base namespace prefix instead of 'ns' -O1 optimize by omitting duplicate choice/sequence members -O2 optimize -O1 and omit unused schema types (unreachable from roots) -O3 optimize -O2 and omit unused schema root attributes -O4 optimize -O3 and omit unused schema root elements (use only with WSDLs) -ofile output to file -P don't create polymorphic types inherited from xsd__anyType -p create polymorphic types inherited from base xsd__anyType -qname use name for the C++ namespace of all declarations -R generate REST operations for REST bindings specified in a WSDL -rhost[:port[:uid:pwd]] connect via proxy host, port, and proxy credentials -r:uid:pwd connect with authentication credentials (digest auth requires SSL) -s don't generate STL code (no std::string and no std::vector) -Sname use name instead of 'soap' for the C++ class members with soap contexts -tfile use type map file instead of the default file typemap.dat -U allow UTF8-encoded Unicode C/C++ identifiers when mapping XML tag names -u don't generate unions -V display the current version and exit -v verbose output -W suppress warnings -w always wrap response parameters in a response struct (<=1.1.4 behavior) -x don't generate _XML any/anyAttribute extensibility elements -y generate typedef synonyms for structs and enums -z1 compatibility with 2.7.6e: generate pointer-based arrays -z2 compatibility with 2.7.7 to 2.7.15: qualify element/attribute references -z3 compatibility with 2.7.16 to 2.8.7: qualify element/attribute references -z4 compatibility up to 2.8.11: don't generate union structs in std::vector -z5 compatibility up to 2.8.15: don't include minor improvements -z6 compatibility up to 2.8.17: don't include minor improvements -z7 compatibility up to 2.8.59: don't generate std::vector of class of union -_ don't generate _USCORE (replace with UNICODE _x005f) infile.wsdl infile.xsd http://www... list of input sources (if none reads stdin) $ soapcpp2 -help Usage: soapcpp2 [-0|-1|-2] [-C|-S] [-T] [-Ecdt] [-L] [-a] [-A] [-b] [-c|-c++|-c++11] [-d path] [-e] [-f N] [-g] [-h] [-i] [-I path:path:...] [-l] [-m] [-n] [-p name] [-Q name] [-q name] [-r] [-s] [-t] [-u] [-V] [-v] [-w] [-x] [-y] [-z#] [infile] -1 generate SOAP 1.1 bindings -2 generate SOAP 1.2 bindings -0 no SOAP bindings, use REST -C generate client-side code only -S generate server-side code only -T generate server auto-test code -Ec generate extra routines for deep copying -Ed generate extra routines for deep deletion -Et generate extra routines for data traversals with walker functions -L don't generate soapClientLib/soapServerLib -a use SOAPAction with WS-Addressing to invoke server-side operations -A require SOAPAction to invoke server-side operations -b serialize byte arrays char[N] as string -c generate C source code -c++ generate C++ source code (default) -c++11 generate C++ source code optimized for C++11 (compile with -std=c++11) -dpath use path to save files -e generate SOAP RPC encoding style bindings (also use -1 or -2) -fN multiple soapC files, with N serializer definitions per file (N>=10) -g generate XML sample messages in template format -h display help info -Ipath use path(s) for #import (paths separated with ':') -i generate C++ service proxies and objects inherited from soap struct -j generate C++ service proxies and objects that share a soap struct -l generate linkable modules (experimental) -m generate Matlab(tm) code for MEX compiler (deprecated) -n use service name to rename service functions and namespace table -pname save files with new prefix name instead of 'soap' -Qname use name as the C++ namespace for decls, including custom serializers -qname use name as the C++ namespace for decls, excluding custom serializers -r generate soapReadme.md report -s generate deserialization code with strict XML validation checks -t generate code for fully xsi:type typed SOAP/XML messaging -u uncomment comments in WSDL/schema output by suppressing XML comments -V display the current version and exit -v verbose output -w don't generate WSDL and schema files -x don't generate sample XML message files -y include C/C++ type access information in sample XML messages -z1 compatibility: generate old-style C++ service proxies and objects -z2 compatibility with 2.7.x: omit XML output for NULL pointers -z3 compatibility with <= 2.8.30: _param_N indexing; nillable pointers infile header file to parse (if none reads stdin)
-
再在该目录下创建ipc目录,将gsoap-2.8\gsoap下的typemap.dat复制到ipc目录
-
在ipc目录执行,生成onvif.h
wsdl2h -s -t typemap.dat -o onvif.h http://www.onvif.org/onvif/ver10/network/wsdl/remotediscovery.wsdl http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl http://www.onvif.org/onvif/ver20/analytics/wsdl/analytics.wsdl http://www.onvif.org/onvif/ver10/analyticsdevice.wsdl http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.onvif.org/onvif/ver10/deviceio.wsdl http://www.onvif.org/onvif/ver10/display.wsdl http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl http://www.onvif.org/onvif/ver10/recording.wsdl http://www.onvif.org/onvif/ver10/replay.wsdl http://www.onvif.org/onvif/ver10/search.wsdl http://www.onvif.org/onvif/ver10/receiver.wsdl http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl
-
在执行以下指令生成对应soapC.c文件等,注空格
soapcpp2 -c onvif.h -x -I import路径 -I gsoap路径
-
将目录拷贝到工程
- 将生成的.nsmap修改其中一个为.h,其他删除即可
- 拷贝gsoap压缩包中的duration.c/h、stdsoap2.c/h到工程目录,
- 需要注意的点
- 以上指令都是在su权限下执行
- 对应的生成server或者client即可,无需全部生成,不然工程浩大
三、测试工具
- 我这边使用的测试工具是:ONVIF Device Test Tool
- 给一个我的版本下载地址: ONVIF Device Test Tool
- 使用介绍: onvif工具使用简介
Android jni工程
onvif_dr.png通过以上可以看到,在soapC.cpp,soapH.h,onvif.h,soapStub.h几个文件,资源占用很大,我这边碰到的第一个问题是工程太大,编译内存不够
GCC编译静态库最多支持2g内存的,故此涉及到库的裁切问题,需要对应删选自己需要的wsdl匹配的代码生成,不然根本编译不过来,我调式了半个小时,发现方案上可行,只是暂时放弃裁切这一块转了另一个方向
给出参考文档:
还有一个方案是在android上集成ksoap2的库,留待有时间慢慢尝试
四、gSoap生成代码中的主要的坑
-
在安装libssl-dev时会出现包的版本冲突问题,这里我们需要使用aptitude来下载
$ sudo apt-get install libssl-dev Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: libssl-dev : Depends: libssl1.0.0 (= 1.0.1-4ubuntu5) but 1.0.1-4ubuntu5.3 is to be installed Recommends: libssl-doc but it is not going to be installed E: Unable to correct problems, you have held broken packages.
-
解决办法:
$sudo apt-get install aptitude $sudo aptitude install libssl-dev (这些命令都是su下执行) //此处对应的选择安装如下: The following NEW packages will be installed: libssl-dev{b} The following packages are RECOMMENDED but will NOT be installed: libssl-doc 0 packages upgraded, 1 newly installed, 0 to remove and 0 not upgraded. Need to get 1,528 kB of archives. After unpacking 6,179 kB will be used. The following packages have unmet dependencies: libssl-dev : Depends: libssl1.0.0 (= 1.0.1-4ubuntu5) but 1.0.1-4ubuntu5.3 is installed. Depends: zlib1g-dev but it is not going to be installed. The following actions will resolve these dependencies: Keep the following packages at their current version: 1) libssl-dev [Not Installed] Accept this solution? [Y/n/q/?] n The following actions will resolve these dependencies: Install the following packages: 1) zlib1g-dev [1:1.2.3.4.dfsg-3ubuntu4 (precise)] Downgrade the following packages: 2) libssl1.0.0 [1.0.1-4ubuntu5.3 (now) -> 1.0.1-4ubuntu5 (precise-updates)] Accept this solution? [Y/n/q/?] y The following packages will be DOWNGRADED: libssl1.0.0 The following NEW packages will be installed: libssl-dev zlib1g-dev{a} The following packages are RECOMMENDED but will NOT be installed: libssl-doc 0 packages upgraded, 2 newly installed, 1 downgraded, 0 to remove and 0 not upgraded. Need to get 2,707 kB of archives. After unpacking 6,575 kB will be used. Do you want to continue? [Y/n/?] y Get: 1 http://mirror.lupaworld.com/ubuntu/ precise-updates/main libssl1.0.0 amd64 1.0.1-4ubuntu5 [1,013 kB] Get: 2 http://mirror.lupaworld.com/ubuntu/ precise/main zlib1g-dev amd64 1:1.2.3.4.dfsg-3ubuntu4 [165 kB] Get: 3 http://mirror.lupaworld.com/ubuntu/ precise-updates/main libssl-dev amd64 1.0.1-4ubuntu5 [1,528 kB] Fetched 2,707 kB in 5s (503 kB/s) Preconfiguring packages ... dpkg: warning: downgrading libssl1.0.0 from 1.0.1-4ubuntu5.3 to 1.0.1-4ubuntu5. (Reading database ... 150648 files and directories currently installed.) Preparing to replace libssl1.0.0 1.0.1-4ubuntu5.3 (using .../libssl1.0.0_1.0.1-4ubuntu5_amd64.deb) ... Unpacking replacement libssl1.0.0 ... Setting up libssl1.0.0 (1.0.1-4ubuntu5) ... Processing triggers for libc-bin ... ldconfig deferred processing now taking place Selecting previously unselected package zlib1g-dev. (Reading database ... 150648 files and directories currently installed.) Unpacking zlib1g-dev (from .../zlib1g-dev_1%3a1.2.3.4.dfsg-3ubuntu4_amd64.deb) ... Selecting previously unselected package libssl-dev. Unpacking libssl-dev (from .../libssl-dev_1.0.1-4ubuntu5_amd64.deb) ... Processing triggers for man-db ... Setting up zlib1g-dev (1:1.2.3.4.dfsg-3ubuntu4) ... Setting up libssl-dev (1.0.1-4ubuntu5) ... 安装完成之后的验证: $dpkg -l *libssl*
网友评论