Android端实现Onvif IPC开发(一)——gSoap移植NDK尝试

@[toc]

Android端实现Onvif IPC开发:

【Android音视频】Onvif-IPC开发(一)——gSoap-onvif移植到Android》
【Android音视频】Onvif-IPC开发(二)——JAVA版本onvif服务器构建Onvif-IP-Camera
【Android音视频】Onvif IPC开发(三)——YUV格式深入浅出
[【Android音视频】Onvif IPC开发(四)——Onvif移植Android架构与补全方案(更新中...) ]

阅读说明(必读)

改动,在我2018年12月1日前,博客一直没跟新这条,前面又说onvif ndk移植失败,不过我后面又调通了,相比于java版本,用java实现显得有点生硬,且容易漏下一些协议内容,导致识别或者控制上的问题,最稳妥的还是用gosap生成的onvif server端去处理协议

移植NDK最主要的问题是生成的OnvifServer工程太大,而关键便在于如何缩小工程量,这边文章整个配置是没有问题的,在环境搭建第5步,根据wsdl生成onvif.h时,需要相应的裁切。我会专门写一篇文章来介绍如何做

本文详解,在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的定义。这里可以通俗的理解为协议定义。

二、环境搭建

  1. 我的开发环境是Ubuntu 16.04 LTS 内存 8G I5 4核

  2. gSoap下载地址:http://www.cs.fsu.edu/~engelen/soap.html,我下载的版本是2.8.66

  3. 下载好解压到工程目录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
    
  4. 此处可对应查看以下工程的指令含义

     $: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)
    
  5. 再在该目录下创建ipc目录,将gsoap-2.8\gsoap下的typemap.dat复制到ipc目录

  6. 在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
    
  7. 在执行以下指令生成对应soapC.c文件等,注空格

     soapcpp2 -c onvif.h -x -I import路径 -I gsoap路径
    
  8. 将目录拷贝到工程

    • 将生成的.nsmap修改其中一个为.h,其他删除即可
    • 拷贝gsoap/custom中的duration.c/h、gsoap/ stdsoap2.c/h到工程目录,
  1. 需要注意的点
    • 以上指令都是在su权限下执行
    • 对应的生成server或者client即可,无需全部生成,不然工程浩大

三、测试工具

  1. 我这边使用的测试工具是:ONVIF Device Test Tool
  2. 给一个我的版本下载地址: ONVIF Device Test Tool
  3. 使用介绍: 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*
    

参考文档:

推荐文档:

  1. 剪裁Onvif:减小soapC.cpp文件的大小(一)
  2. 剪裁Onvif:减小soapC.cpp文件的大小(二)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容