1. 程式人生 > >【Android音視訊】Android Onvif-IPC開發(一)——gSoap移植NDK嘗試

【Android音視訊】Android Onvif-IPC開發(一)——gSoap移植NDK嘗試

Android端實現Onvif IPC開發:

閱讀說明(必讀)

我在進行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的定義。這裡可以通俗的理解為協議定義。

二、環境搭建

  1. 我的開發環境是Ubuntu 16.04 LTS 記憶體 8G I5 4核

  2. 下載好解壓到工程目錄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
    
  3. 此處可對應檢視以下工程的指令含義

     $: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)
    
  4. 再在該目錄下建立ipc目錄,將gsoap-2.8\gsoap下的typemap.dat複製到ipc目錄

  5. 在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
    
  6. 在執行以下指令生成對應soapC.c檔案等,注空格

     soapcpp2 -c onvif.h -x -I import路徑 -I gsoap路徑
    
  7. 將目錄拷貝到工程

    • 將生成的.nsmap修改其中一個為.h,其他刪除即可
    • 拷貝gsoap壓縮包中的duration.c/h、stdsoap2.c/h到工程目錄,
  8. 需要注意的點

    • 以上指令都是在su許可權下執行
    • 對應的生成server或者client即可,無需全部生成,不然工程浩大

三、測試工具

  1. 我這邊使用的測試工具是:ONVIF Device Test Tool

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*