顯示具有 gSOAP 標籤的文章。 顯示所有文章
顯示具有 gSOAP 標籤的文章。 顯示所有文章

2015年11月3日 星期二

在 iOS 設備上使用 gSoap

本篇以 WSDiscovery 為例,說明如何在 iOS 上使用 gSOAP ,
使用的軟體版本為  gSOAP  2.8.19 與 XCODE  6.4

1. 取得軟體
gSOAP 可從 sourceforge 下載,  xcode 可從 Mac 內建的 AppStore取得。

2. 用 gSOAP 產生需要的程式碼,詳細作法可參考此篇文章


3. 可選擇使用 iOS plugin,或自行實作網路介面
iOS plugin 利用 iOS 的 NSURL 與 NSMutableURLRequest 來實作傳送與接收 HTTP 層的資料,使用範例如下: 
 #import "gsoapios.h"
struct soap *soap = soap_new();
soap_register(soap, soap_ios); // Register the iOS plugin
 ...
soap_end(soap);  // clean up allocated temporaries
soap_destroy(soap); // Free soap context 
iOS plugin 的方法簡介
  • 設定 Cache Policy
soap_ios_setchacepolicy(soap, NSURLRequestReturnCacheDataElseLoad); 
  • 設定timeout
soap_ios_settimeoutinterval(soap, 30.0); 
  • 設定帳號密碼
soap->userid = "someone";
soap->passwd = "somepass";
   
4. 以wsdiscovery 為例,實作方式摘錄如下
a.直接取得 wsdiscovery 程式碼
git clone https://github.com/alb423/wsdiscovery
b.開啟 xcode, 新增一個 project, 將 wsdiscovery 目錄內的檔案都新增至 Project (main.c除外) 
c. 新增 wsdiscovery_api.m,參考 main.c 進行小量修改 
d. 開始編譯。此時會出現幾種錯誤,主要其解決方式如下
d1. 找不到 NSString,在 gsoapios.h 加入include file 即可,如下:
#import <UIKit\UIKit.h>
d2. 找不到 DLog,在 gsoapios.h 自行定義即可,如下:
#ifdef DEBUG
#define DLog NSLog
#else
#define DLog(X, ...) ;;;
#endif         
d3. ARC (Automatic Reference Counting), 
可設定 gsoapios.m 不使用 ARC,設定方式為 Target -> Build Phases -> Compile Sources -> 選擇 gsoapios.m,輸入 -fno-objc-arc即可。如下圖

   
d4. "ARC forbids Objective-C objects in struct"
將 GSoapiOSURLData *url_data;
改為 __unsafe_unretained GSoapiOSURLData *url_data;
 
5. 本範例直接操作 socket,並不需要 HTTP,因此沒有用到 iOS plugin。接下來我將會在 iOS 上使用 gSOAP 與 ONVIF command 結合,並藉由這個範例來測試 iOS plugin。

註1: 範例程式碼可從 https://github.com/alb423/wsdiscovery 下載
註2: 針對 ARC 錯誤,也可以請 Xcode 自動將程式碼轉換成 ARC。作法是 Edit -> Convert -> Convert to Objective-C ARC...,可參考此篇文章 http://onevcat.com/2012/06/arc-hand-by-hand/

2013年9月18日 星期三

ONVIF -- WS-Discovery implementation

Here is a guide to teach you how to implement WS-Discovery by gSOAP. You can also find sample code here.

1. Xml Schema of WS-Discovery 

Use the typemap.dat file located in "\gsoap-2.8\gsoap\wsdl\".
WS-Discovery is already defined in typemap.dat.
 1 # WS-Discovery 1.1 and 1.0
 2 
 3 wsdd = <http://docs.oasis-open.org/ws-dd/ns/discovery/2009/01>
 4 wsdd10 = <http://schemas.xmlsoap.org/ws/2005/04/discovery>
 5 
 6 wsdd10__HelloType  = | wsdd__HelloType
 7 wsdd10__ByeType   = | wsdd__ByeType
 8 wsdd10__ProbeType  = | wsdd__ProbeType
 9 wsdd10__ProbeMatchesType = | wsdd__ProbeMatchesType
10 wsdd10__ProbeMatchType  = | wsdd__ProbeMatchType
11 wsdd10__ResolveType  = | wsdd__ResolveType
12 wsdd10__ResolveMatchesType = | wsdd__ResolveMatchesType
13 wsdd10__ResolveMatchType = | wsdd__ResolveMatchType
14 wsdd10__ScopesType  = | wsdd__ScopesType
15 wsdd10__SecurityType  = | wsdd__SecurityType
16 wsdd10__SigType   = | wsdd__SigType
17 wsdd10__AppSequenceType  = | wsdd__AppSequenceType

2013年9月11日 星期三

ONVIF -- Support Customized Event

If you want to support a customized event which not belong to ONVIF spec.
You can follow below setup to re-generate your gSoap code by gSOAP.

1. Revise WS-typemap.dat to add customized namespace
tnsMy = <http://www.avigilon.com/onvif/ver10/topics>

2013年8月2日 星期五

gSOAP -- Empty Element Tag 的產生規則整理

若一個 xml elemnt 為空,一般有兩種表示方式。
<tag></tag>
<tag />

那麼當使用 gSoap 建議的 onvif schema 產生程式碼後,如何確認哪些函數會生成 <tag />的形式呢?
gSOAP 的 stdsoap2.c中會透過soap_element_start_end_out()函數產生 "/>" 的標籤,而透過 onvif schema 所產生的程式碼,主要會透過呼叫 stdsoap2.c其中的三個函數 soap_element_href(), soap_element_null(), soap_element_nil()來產生 "/>" 的標籤。 
由於 gSoap 會自動根據 wsdl 產生 header file, 接著自動產生程式碼。
因此若我們想要強制其產生</>,則不應該手動呼叫上述的三個函數,
而應該了解其生成原理。藉著修改wsdl, 或是 header file, 來達成此功能。

2013年5月21日 星期二

MTOM (Message Transmission Optimization Mechanism)


當我們要在 xml 中傳送一組binary資料時,一般的作法是將此資料先使用Base64編碼,再送出,如此會使得此資料大小增加為原本的 4/3 倍。

為此,W3C定義了MTOM方法,當傳送大量的資料時,可以減少所需的資料傳輸量。
MTOM 的原理是使用 XOP (XML-binary Optimized Packaging) 來封裝 binary 資料,目前 XOP 只定義使用一種封裝方法,就是 MIME Multipart/Related。

以下將介紹一個 MTOM 的例子,並介紹如何利用 gSOAP 取得 MTOM 資料

2012年12月28日 星期五

使用 gSoap 2.8.12 產生 ONVIF 程式碼


20121229 更新

1. gSOAP 最新版本為 2.8.12, 此版本在 FAQ 中註明了 ONVIF 程式產生時的 define namespace prefix and type bindings,如此在開發程式時可有一個統一的命名規則。如下:

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"

2012年10月14日 星期日

gSoap -- 小技巧分享

紀錄使用 gSoap 開發 ONVIF 時所用的一些小技巧。

1. 取出 Client 所送的 HTTP data。
若需要存取HTTP的原始資料,可以直接使用 zsoap->buf, zsoap->buflen 這兩個資料結構。

2012年7月25日 星期三

ONVIF -- 透過 gSOAP 產生程式碼



gSOAP 可以幫忙將 wsdl 所定義的 schema 轉換成對應的程式碼,以下紀錄如何轉換的過程。


操作步驟

一、下載 gSOAP
連結 http://gsoap2.sourceforge.net/,下載 gSOAP,此篇文章撰寫時的最新版本為 2.8.9 。
 
二、利用 wsdl2h.exe ,產生 header files,此處以 media.wsdl 為例
wsdl2h.exe -c -o media.h http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl http://www.w3.org/2006/03/addressing/ws-addr.xsd 

三、使用 header file 產生程式碼,若 header file 較大,則需較長的產生時間。
soapcpp2 -C –I../../import  media.h
註:"-C"表示產生Client端的程式碼,改成"-S"便會產生Server端程式碼。

四、成功後,會產生 149 個檔案,如下
media.h
MediaBinding.AddAudioDecoderConfiguration.req.xml
MediaBinding.AddAudioDecoderConfiguration.res.xml
MediaBinding.AddAudioEncoderConfiguration.req.xml
MediaBinding.AddAudioEncoderConfiguration.res.xml
MediaBinding.AddAudioOutputConfiguration.req.xml
MediaBinding.AddAudioOutputConfiguration.res.xml
MediaBinding.AddAudioSourceConfiguration.req.xml
MediaBinding.AddAudioSourceConfiguration.res.xml
MediaBinding.AddMetadataConfiguration.req.xml
MediaBinding.AddMetadataConfiguration.res.xml
MediaBinding.AddPTZConfiguration.req.xml
MediaBinding.AddPTZConfiguration.res.xml
MediaBinding.AddVideoAnalyticsConfiguration.req.xml
MediaBinding.AddVideoAnalyticsConfiguration.res.xml
MediaBinding.AddVideoEncoderConfiguration.req.xml
MediaBinding.AddVideoEncoderConfiguration.res.xml
MediaBinding.AddVideoSourceConfiguration.req.xml
MediaBinding.AddVideoSourceConfiguration.res.xml
MediaBinding.CreateProfile.req.xml
MediaBinding.CreateProfile.res.xml
MediaBinding.DeleteProfile.req.xml
MediaBinding.DeleteProfile.res.xml
MediaBinding.GetAudioDecoderConfiguration.req.xml
MediaBinding.GetAudioDecoderConfiguration.res.xml
MediaBinding.GetAudioDecoderConfigurationOptions.req.xml
MediaBinding.GetAudioDecoderConfigurationOptions.res.xml
MediaBinding.GetAudioDecoderConfigurations.req.xml
MediaBinding.GetAudioDecoderConfigurations.res.xml
MediaBinding.GetAudioEncoderConfiguration.req.xml
MediaBinding.GetAudioEncoderConfiguration.res.xml
MediaBinding.GetAudioEncoderConfigurationOptions.req.xml
MediaBinding.GetAudioEncoderConfigurationOptions.res.xml
MediaBinding.GetAudioEncoderConfigurations.req.xml
MediaBinding.GetAudioEncoderConfigurations.res.xml
MediaBinding.GetAudioOutputConfiguration.req.xml
MediaBinding.GetAudioOutputConfiguration.res.xml
MediaBinding.GetAudioOutputConfigurationOptions.req.xml
MediaBinding.GetAudioOutputConfigurationOptions.res.xml
MediaBinding.GetAudioOutputConfigurations.req.xml
MediaBinding.GetAudioOutputConfigurations.res.xml
MediaBinding.GetAudioOutputs.req.xml
MediaBinding.GetAudioOutputs.res.xml
MediaBinding.GetAudioSourceConfiguration.req.xml
MediaBinding.GetAudioSourceConfiguration.res.xml
MediaBinding.GetAudioSourceConfigurationOptions.req.xml
MediaBinding.GetAudioSourceConfigurationOptions.res.xml
MediaBinding.GetAudioSourceConfigurations.req.xml
MediaBinding.GetAudioSourceConfigurations.res.xml
MediaBinding.GetAudioSources.req.xml
MediaBinding.GetAudioSources.res.xml
MediaBinding.GetCompatibleAudioDecoderConfigurations.req.xml
MediaBinding.GetCompatibleAudioDecoderConfigurations.res.xml
MediaBinding.GetCompatibleAudioEncoderConfigurations.req.xml
MediaBinding.GetCompatibleAudioEncoderConfigurations.res.xml
MediaBinding.GetCompatibleAudioOutputConfigurations.req.xml
MediaBinding.GetCompatibleAudioOutputConfigurations.res.xml
MediaBinding.GetCompatibleAudioSourceConfigurations.req.xml
MediaBinding.GetCompatibleAudioSourceConfigurations.res.xml
MediaBinding.GetCompatibleMetadataConfigurations.req.xml
MediaBinding.GetCompatibleMetadataConfigurations.res.xml
MediaBinding.GetCompatibleVideoAnalyticsConfigurations.req.xml
MediaBinding.GetCompatibleVideoAnalyticsConfigurations.res.xml
MediaBinding.GetCompatibleVideoEncoderConfigurations.req.xml
MediaBinding.GetCompatibleVideoEncoderConfigurations.res.xml
MediaBinding.GetCompatibleVideoSourceConfigurations.req.xml
MediaBinding.GetCompatibleVideoSourceConfigurations.res.xml
MediaBinding.GetGuaranteedNumberOfVideoEncoderInstances.req.xml
MediaBinding.GetGuaranteedNumberOfVideoEncoderInstances.res.xml
MediaBinding.GetMetadataConfiguration.req.xml
MediaBinding.GetMetadataConfiguration.res.xml
MediaBinding.GetMetadataConfigurationOptions.req.xml
MediaBinding.GetMetadataConfigurationOptions.res.xml
MediaBinding.GetMetadataConfigurations.req.xml
MediaBinding.GetMetadataConfigurations.res.xml
MediaBinding.GetProfile.req.xml
MediaBinding.GetProfile.res.xml
MediaBinding.GetProfiles.req.xml
MediaBinding.GetProfiles.res.xml
MediaBinding.GetServiceCapabilities.req.xml
MediaBinding.GetServiceCapabilities.res.xml
MediaBinding.GetSnapshotUri.req.xml
MediaBinding.GetSnapshotUri.res.xml
MediaBinding.GetStreamUri.req.xml
MediaBinding.GetStreamUri.res.xml
MediaBinding.GetVideoAnalyticsConfiguration.req.xml
MediaBinding.GetVideoAnalyticsConfiguration.res.xml
MediaBinding.GetVideoAnalyticsConfigurations.req.xml
MediaBinding.GetVideoAnalyticsConfigurations.res.xml
MediaBinding.GetVideoEncoderConfiguration.req.xml
MediaBinding.GetVideoEncoderConfiguration.res.xml
MediaBinding.GetVideoEncoderConfigurationOptions.req.xml
MediaBinding.GetVideoEncoderConfigurationOptions.res.xml
MediaBinding.GetVideoEncoderConfigurations.req.xml
MediaBinding.GetVideoEncoderConfigurations.res.xml
MediaBinding.GetVideoSourceConfiguration.req.xml
MediaBinding.GetVideoSourceConfiguration.res.xml
MediaBinding.GetVideoSourceConfigurationOptions.req.xml
MediaBinding.GetVideoSourceConfigurationOptions.res.xml
MediaBinding.GetVideoSourceConfigurations.req.xml
MediaBinding.GetVideoSourceConfigurations.res.xml
MediaBinding.GetVideoSources.req.xml
MediaBinding.GetVideoSources.res.xml
MediaBinding.nsmap
MediaBinding.RemoveAudioDecoderConfiguration.req.xml
MediaBinding.RemoveAudioDecoderConfiguration.res.xml
MediaBinding.RemoveAudioEncoderConfiguration.req.xml
MediaBinding.RemoveAudioEncoderConfiguration.res.xml
MediaBinding.RemoveAudioOutputConfiguration.req.xml
MediaBinding.RemoveAudioOutputConfiguration.res.xml
MediaBinding.RemoveAudioSourceConfiguration.req.xml
MediaBinding.RemoveAudioSourceConfiguration.res.xml
MediaBinding.RemoveMetadataConfiguration.req.xml
MediaBinding.RemoveMetadataConfiguration.res.xml
MediaBinding.RemovePTZConfiguration.req.xml
MediaBinding.RemovePTZConfiguration.res.xml
MediaBinding.RemoveVideoAnalyticsConfiguration.req.xml
MediaBinding.RemoveVideoAnalyticsConfiguration.res.xml
MediaBinding.RemoveVideoEncoderConfiguration.req.xml
MediaBinding.RemoveVideoEncoderConfiguration.res.xml
MediaBinding.RemoveVideoSourceConfiguration.req.xml
MediaBinding.RemoveVideoSourceConfiguration.res.xml
MediaBinding.SetAudioDecoderConfiguration.req.xml
MediaBinding.SetAudioDecoderConfiguration.res.xml
MediaBinding.SetAudioEncoderConfiguration.req.xml
MediaBinding.SetAudioEncoderConfiguration.res.xml
MediaBinding.SetAudioOutputConfiguration.req.xml
MediaBinding.SetAudioOutputConfiguration.res.xml
MediaBinding.SetAudioSourceConfiguration.req.xml
MediaBinding.SetAudioSourceConfiguration.res.xml
MediaBinding.SetMetadataConfiguration.req.xml
MediaBinding.SetMetadataConfiguration.res.xml
MediaBinding.SetSynchronizationPoint.req.xml
MediaBinding.SetSynchronizationPoint.res.xml
MediaBinding.SetVideoAnalyticsConfiguration.req.xml
MediaBinding.SetVideoAnalyticsConfiguration.res.xml
MediaBinding.SetVideoEncoderConfiguration.req.xml
MediaBinding.SetVideoEncoderConfiguration.res.xml
MediaBinding.SetVideoSourceConfiguration.req.xml
MediaBinding.SetVideoSourceConfiguration.res.xml
MediaBinding.StartMulticastStreaming.req.xml
MediaBinding.StartMulticastStreaming.res.xml
MediaBinding.StopMulticastStreaming.req.xml
MediaBinding.StopMulticastStreaming.res.xml
soapC.c
soapClient.c
soapClientLib.c
soapH.h
soapStub.h

五、參考 soapStub.h,實作對應的函數,例如:soap_serve___ns2__GetStreamUri(struct soap*);,此處,我將所有相關的函數統一放在soapStub.c內。


六、若要產生完整的 onvif API,則可以加入所有 onvif 所定義的 wsdl, 參考下列指令

wsdl2h.exe -c -o onvif.h
http://www.onvif.org/onvif/ver10/schema/onvif.xsd
http://www.w3.org/2006/03/addressing/ws-addr.xsd
http://www.onvif.org/onvif/ver10/device/wsdl/devicemgmt.wsdl
http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl
http://www.onvif.org/onvif/ver10/deviceio.wsdl
http://docs.oasis-open.org/wsrf/rw-2.wsdl
http://docs.oasis-open.org/wsn/bw-2.wsdl
http://www.onvif.org/onvif/ver10/event/wsdl/event.wsdl
http://www.onvif.org/onvif/ver20/ptz/wsdl/ptz.wsdl
http://www.onvif.org/onvif/ver20/imaging/wsdl/imaging.wsdl


問題釋疑

1. Critical error: #import: Cannot open file "ns1.h" for reading.
    wsdl2h.exe 使用時加入 http://www.w3.org/2006/03/addressing/ws-addr.xsd 即可。


2. 編譯時發現少了 stdsoap2.h
    此檔案可在 \gsoap_2.8.9\gsoap-2.8\gsoap\ 取得。
    複製時應該同時複製 stdsoap2.h 與 stdsoap2.c


3. Makefile 舉例,因為我在 Windows 使用 mingw 來編譯,其Makefile 如下
OBJS = stdsoap2.o soapC.o soapClient.o soapClientLib.o soapStub.o
all: onvif_media
%.o: %.c soapH.h soapStub.h import/*.h
gcc -c $< -o $@
onvif_media: $(OBJS)
gcc $(OBJS) -o $@
clean:
rm -f *.o onvif_media.exe

參考資料:

  1. wsdl2h 與 soapcpp2 用法
  2. gSOAP 中文使用介紹
  3. http://www.cppblog.com/qiujian5628/archive/2008/10/11/54019.html