2013年11月21日 星期四

ONVIF之痛苦往事

若說技術,世界上比我厲害的人太多了。
不妨聊聊一點技術之外的事。

想當年做ONVIF時,哪裏知道ONVIF是什麼玩意?更何況是公司做了二代失敗發臭的案子,落到我頭上。長官指定,焉有說不的道理?當年可還沒有所謂的「半澤直樹」‥家裏有一家老小要養,正所謂上有八十老母,下有八歲小兒,豈有「做不出來的道理」。。只好硬著頭皮答應下來。

        這一答應下來不得了,光發現ONVIF裝置就去掉了二個月,自己壓給上司的日期就三個月,而ONVIF有將近快200個函式要實做,求救?大家都忙著呢‥總之,自己只能咬牙幹了。

        這一戰下來,ONVIF的確是實做了99%,也對自己的能力有了更深的認識,原來,人的能力是可以這樣被激發的‥
        想辦法反組譯ONVIF TestTool的測試程式,了解它到底要什麼‥(原來是.Netframwork寫的)
        為了解「時間」的問題,用上了Boost函式庫‥
        為了解「空間」的問題,想辦法清除公司舊產品的函式庫,將code擠進Flash‥
最後,的確是完成了,我也離職了。並不是因為被榨光而離職,而是因為對公司未來的不確定。
        經此一役,有如人生的一大成長,對自己的能力有更深一層的認識,才有後來的WOSA/XFS(註:又是另一段故事了)。所以,若目前還在研發上受苦的同志們,別怕,突破了,你就會像「天蠺變」的雲飛揚一樣,功力將會更上一層樓!
       
   


   

2013年8月28日 星期三

長官視察

        話說10年前,個人仍在軍中服志願役時,營上軍官只剩營輔導長及我這個二條槓的中尉連長,全營軍士官兵大都放假,營上各連只剩留守小貓二三隻。本連長從來都看小兵一沒事做就很礙眼,一看全連閒來無事,便叫連上小兵把所有的寢具全部都拿出來連集合場曬曬太陽,讓他們忙個一上午,然後我準備營區逛大街~~。

        若是「大頭兵日記」的編劇,此時正是下筆精彩的時刻,風雨前的寧靜,長官不出現何時出現呢?果然,營門衛兵通報,長官視察,只見一輛黑頭車疾駛進營區。「哇哩嘞‥師長」居然是最高長官到,大事不妙,全營有如掀開臭水溝蓋的蟑螂,各路人馬紛紛逃竄躲藏,營輔導長小跑步的跟上師長到處巡視。
        「部隊集合,所有人5分鐘內,營集合場集合」營值星官就是敝人在下我,一道命令下去,呼叫所有牛鬼蛇神通通集合。「稍息,立.......正」用了最宏亮的聲音將部隊交給營輔導長。
          當過兵的人有見過長官視察會有好事發生的嗎?所有人屁股都夾的緊緊的,準備等著師長開口罵人。
         「第三連,誰在?」要糟,師長第一個就指名敝連,「莫非,我叫傳令給我弄的那個獨立的浴室被師長看到了?還附了一個要命的蓮蓬頭‥死了‥」這手舉還是不舉呢?連上的值星官居然也裝死不趕快舉手,難道要我這個連長上去頂嗎?好,就給我記著,等我被罵完,你們這些人也不會有好日子過,心念轉了好幾下,不得不舉起手來。
           「報告師長,第三連連長!」
            「果然有連長在就是不一樣,知道利用在營的官兵來曬寢具,手放下。」此時差點沒有大叫三聲:耶耶耶!!!
             剛剛沒幫忙舉手幫我頂的我就先放過你們了,這讚美我領啦,哈哈!想不到一下子居然從地獄變成天堂保證班。

              這一個讚美和幸運,經過了十年還印象深刻的印在腦海中,雖然當初只是無心插柳,多下了那一道命令,後續的情節,其實我忘得差不多,多下的那一道命令,其實就是上級長官想看的,部隊有為有守,不是每天打混摸魚。只不過我當初哪想得到那麼多~

               為什麼會提起這件事呢?日後的工作,常常也發生類似的場面,只是「連長」不是我,看著有時候長官被釘或者是出包,就會心想:「唉,長官大人你怎麼不多做一點呢?」。

想事情的時候,最好要拉高一個層級,通常就能猜得到長官的意思,管理好長官,自己也好做事~但是猜心思,和拍馬屁又是兩回事了‥待續。

ONVIF Ws-discovery

自從發表了ONVIF Ws-discovery一文,認為應該有有進一步的解說,筆者當初在開發Onvif時,最難的不是Device Service,而是Test tool怎麼都發現不到我寫的設備(可參閱上一篇Onvif一二事)。

於是找了Ws-discovery的說明書後,發現只要根據下列幾個原則,Test tool即可發現符合Onvif規定的設備了,一定要先被發現,之後才能做服務嘛‥萬事起頭難。

說簡單也簡單,Ws-discovery採取廣播的方式來尋找設備,廣播位址為:239.255.255.250,port :3702

回應時需注意下列幾個注意事項:
1.設備服務的ID值:(請自行產生)
EndpointReference.Address = "532E5B51-6579-40f0-A79E-51394EDD1744"

2.產品的名稱
ProbeMatch->Scopes->item =  "onvif://www.onvif.org/type/video_encoder onvif://www.onvif.org/type/audio_encoder onvif://www.onvif.org/name/virtual-ipcam onvif://www.onvif.org/location/Taipei"

3.這個裝置是在Onvif分類上的哪一個大類
ProbeMatch->Types =  "dn:NetworkVideoTransmitter"

4.此裝置提供服務的實體位址
ProbeMatches->ProbeMatch->XAddrs =  "http://192.168.3.100/onvif/service"

5.每次回應時都要重產生一個Message ID
soap->header->wsa__MessageID = "uuid:urn:uuid:532E5B51-6579-40f0-A79E-51394EDD1734"

以下是範例程式執行時的畫面:ws_discovery.exe "主機IP", 此時將會聽取來 239.255.255.250:3702的訊息。


然後,再執行Onvif官方的Test Tool,執行後請按[Discovery] 鍵,如下畫面:
則會偵測到我們ws_discovery.exe發出來的回應訊息。
此時表示我們這個虛擬的Onvif設備已經被TestTool找到了。

原始碼下載點:
https://docs.google.com/file/d/0B69QoydOaKOrX29FcFR6WHdWUjg/edit?usp=sharing









2011年8月4日 星期四

ONVIF Discovery的一二事

很多在做ONVIF的人用remotediscovery.wsdl + gsoap產生出soap的程式,但是~~~
若是用官方的頁面所發佈的remotediscovery.wsdl做出來的程式可以讓TestTool有反應的話,那我就得稱看官你不是人,而是神!
            第一,它產生出來的欄位就不太符合[ws-discovery]文件所敘述的欄位。Ex:沒有ProbeMatches欄
            第二,Test Tool也會去檢查這一個欄位。
所以,若根據官方發佈的remotediscovery.wsdl這個東東,大大們能得到正確的Discovery的話,真的是佩服的五體投地。

修正如下:
<wsdl:definitions
xmlns:dn="http://schemas.xmlsoap.org/ws/2005/04/discovery"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:wl="http://www.onvif.org/ver10/network/wsdl"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.xmlsoap.org/ws/2005/04/discovery">
 <wsdl:types>
  <xs:schema targetNamespace="http://schemas.xmlsoap.org/ws/2005/04/discovery"
                           xmlns:d="http://schemas.xmlsoap.org/ws/2005/04/discovery"
                           elementFormDefault="qualified">
   <xs:import namespace="http://schemas.xmlsoap.org/ws/2005/04/discovery"
                           schemaLocation="http://schemas.xmlsoap.org/ws/2005/04/discovery/ws-discovery.xsd%22/>
   <!--  Message Request/Responses elements  -->
   <!--===============================-->
   <xs:element name="Hello" type="d:HelloType"/>
   <xs:element name="HelloResponse" type="d:ResolveType"/>
   <xs:element name="Probe" type="d:ProbeType"/>
   <xs:element name="ProbeMatches" type="d:ProbeMatches"/>
   <xs:element name="Bye" type="d:ByeType"/>
   <xs:element name="ByeResponse" type="d:ResolveType"/>
   <!--===============================-->
  </xs:schema>
 </wsdl:types>
 <wsdl:message name="HelloRequest">
  <wsdl:part name="parameters" element="dn:Hello"/>
 </wsdl:message>
 <wsdl:message name="HelloResponse">
  <wsdl:part name="parameters" element="dn:HelloResponse"/>
 </wsdl:message>
 <wsdl:message name="ProbeRequest">
  <wsdl:part name="parameters" element="dn:Probe"/>
 </wsdl:message>
 <wsdl:message name="ProbeMatches">
  <wsdl:part name="parameters" element="dn:ProbeMatches"/>
 </wsdl:message>
 <wsdl:message name="ByeRequest">
  <wsdl:part name="parameters" element="dn:Bye"/>
 </wsdl:message>
 <wsdl:message name="ByeResponse">
  <wsdl:part name="parameters" element="dn:ByeResponse"/>
 </wsdl:message>
 <wsdl:portType name="RemoteDiscoveryPort">
  <wsdl:operation name="Hello">
   <wsdl:input message="dn:HelloRequest" dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Hello%22/>
   <wsdl:output message="dn:HelloResponse" dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe%22/>
  </wsdl:operation>
  <wsdl:operation name="Bye">
   <wsdl:input message="dn:ByeRequest" dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Bye%22/>
   <wsdl:output message="dn:ByeResponse"/>
  </wsdl:operation>
 </wsdl:portType>
 <wsdl:portType name="DiscoveryLookupPort">
  <wsdl:operation name="Probe">
   <wsdl:input message="dn:ProbeRequest" dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe%22/>
   <wsdl:output message="dn:ProbeMatches" dn:Action="http://schemas.xmlsoap.org/ws/2005/04/discovery/ProbeMatches%22/>
  </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="RemoteDiscoveryBinding" type="dn:RemoteDiscoveryPort">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http%22/>
  <wsdl:operation name="Hello">
   <soap:operation soapAction="http://www.onvif.org/ver10/network/wsdl/Hello%22/>
   <wsdl:input>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:output>
  </wsdl:operation>
  <wsdl:operation name="Bye">
   <soap:operation soapAction="http://www.onvif.org/ver10/network/wsdl/Bye%22/>
   <wsdl:input>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <wsdl:binding name="DiscoveryLookupBinding" type="dn:DiscoveryLookupPort">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http%22/>
  <wsdl:operation name="Probe">
   <soap:operation soapAction="http://www.onvif.org/ver10/network/wsdl/Probe%22/>
   <wsdl:input>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:input>
   <wsdl:output>
    <soap:body parts="parameters" use="literal"/>
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
</wsdl:definitions>

完畢之後,再將產生出來的*.nsmap檔加上這行
 {"dn", "http://www.onvif.org/ver10/network/wsdl", NULL, NULL},
保證你的discovery就大功告成了!!
相關文章:Onvif ws-discovery

2011年5月29日 星期日

當講師課程有感~

        為了經濟上的需要,有時候會去客串當講師,把自己工作上的經驗,拿來換成「金幣」
當講師,除了口條是基本要求,還得把想講的內容關鍵完整的講出來,卻又不能傷害到原公司或是原單位,還要加上sample code,及講義的製作‥一切都得拿捏到好處。
       
         最近去當了某某課程的講師,講義上的內容可以讓學生按步就班的做出結果~當然身為講師的我,也準備了「標準答案」,但是我想問題是:來上課的是工程師,應該就要有追根究柢的精神。
         缺乏了這樣的精神,只求「標準答案」,今天是XXXX明天又會是什麼?很多的答案是要自己去找出來的~是否我們都中了「基測」的毒?
         自己的講義也搞了個「建構式」教學,把解題的想法寫了出來,希望學員明白整個的解決問題的思考過程,中間過程中有了很多的枝葉‥事實上這也是做專案子會碰到的問題。
(明明要解這個問題,卻又先牽拖到別的問題‥),反而忽略了主題?真是有點順了姑意,逆了嫂意~
         期許「工程師」們要有挑戰自己的精神!除了要有基本「解題」的能力,最好還有「創新」和「發明」的能力‥共勉之~