2008年3月31日 星期一

SIP Intro --- Standard Subscriber Line Tones

Line tones

取自E.182這個doc


E.182定義了標準會用到的Tones如下:

Dial tone: The exchange is ready to receive address information.

PABX internal dial tone: The PABX is ready to receive address information.

Special dial tone: Same as dial tone, but the caller’s line is subject to a specific condition, such as call diversion or a voice mail is available (e.g., "stutter dial tone").

Second dial tone: The network has accepted the address information, but additional information is required.

Ring: This named signal event causes the recipient to generate an alerting signal ("ring"). The actual tone or other indication used to render this named event is left up to the receiver. (This differs from the ringing tone, below, heard by the caller

Ringing tone: The call has been placed to the callee and a calling signal (ringing) is being transmitted to the callee. This tone is also called "ringback".

Special ringing tone: A special service, such as call forwarding or call waiting, is active at the called number.

Busy tone: The called telephone number is busy.

Congestion tone: Facilities necessary for the call are temporarily unavailable.

Calling card service tone: The calling card service tone consists of 60 ms of the sum of 941 Hz and 1477 Hz tones (DTMF ’#’), followed by 940 ms of 350 Hz and 440 Hz (U.S. dial tone), decaying exponentially with a time constant of 200 ms.

Special information tone: The callee cannot be reached, but the reason is neither "busy" nor "congestion". This tone should be used before all call failure announcements, for the benefit of automatic equipment.

Comfort tone: The call is being processed. This tone may be used during long post-dial delays, e.g., in international connections.

Hold tone: The caller has been placed on hold.

Record tone: The caller has been connected to an automatic answering device and is requested to begin speaking.

Caller waiting tone: The called station is busy, but has call waiting service.

Pay tone: The caller, at a payphone, is reminded to deposit additional coins.

Positive indication tone: The supplementary service has been activated.

Negative indication tone: The supplementary service could not be activated.

Off-hook warning tone: The caller has left the instrument off-hook for an extended period of time.


Call waiting tone: Another party wants to reach the subscriber.

Warning tone: The call is being recorded. This tone is not required in all jurisdictions.

Intrusion tone: The call is being monitored, e.g., by an operator.

CPE alerting signal: A tone used to alert a device to an arriving in-band FSK data transmission. A CPE alerting signal is a combined 2130 and 2750 Hz tone, both with tolerances of 0.5% and a duration of 80 to. 80 ms. The CPE alerting signal is used with ADSI services and Call Waiting ID services [14].

Payphone recognition tone: The person making the call or being called is using a payphone (and thus it is ill-advised to allow collect calls to such a person).


另外也定義Event與其encode

Event                     encoding (decimal)
_____________________________________________
Off Hook                                 64
On Hook                                  65
Dial tone                                66
PABX internal dial tone                  67
Special dial tone                        68
Second dial tone                         69
Ringing tone                             70
Special ringing tone                     71
Busy tone                                72
Congestion tone                          73
Special information tone                 74
Comfort tone                             75
Hold tone                                76
Record tone                              77
Caller waiting tone                      78
Call waiting tone                        79
Pay tone                                 80
Positive indication tone                 81
Negative indication tone                 82
Warning tone                             83
Intrusion tone                           84
Calling card service tone                85
Payphone recognition tone                86
CPE alerting signal (CAS)                87
Off-hook warning tone                    88
Ring                                     89


後續會做說明補充...

SIP Intro --- DTMF (轉貼&精簡)

DTMF (Dual Tone Multi-Frequency)
本文參考來源以及RFC2833


DTMF(Dual Tone Multi-Frequency)signaling,逐漸在全世界範圍內使用在按鍵式電話機上,因其提供更高的撥號速率,迅速取代了傳統轉盤式電話機使用的撥號脈衝信令。在VOIP中,DTMF仍是發揮著重要的作用。

一個DTMF信號由兩個頻率的音訊信號疊加構成。這兩個音訊信號的頻率來自兩組預分配的頻率組:行頻組或列頻組。每一對這樣的音訊信號唯一表示一個數位或符號。產生DTMF信號,就是利用兩個不同頻率的正弦波疊加以後形成的波形,解碼時則採用改進的Goertzel演算法,從頻域搜索兩個正弦波的存在。


1209 Hz   1336 Hz     1477 Hz    1633 Hz
ABC        DEF
697 Hz     1          2          3         A
GHI        JKL        MNO
770 Hz     4          5          6         B
PRS        TUV        WXY
852 Hz     7          8          9         C
oper
941 Hz     *          0          #         D


DTMF在VOIP中的解決方案
由於在IP網中的通信傳輸是採packet switch而不是傳統領域中的circuit switch以及IP網的不穩定的特性,DTMF在VOIP中應用的解決方案和傳統有所不同,並且暫時還未統一,有多種解決方案。主要有下列幾種:

1.用SIP的INFO方法攜帶DTMF信號

2.在RTP媒體傳輸中攜帶DTMF信號(此種又有In band與Out of band之分)

3.動態生成DTMF音訊信號



關於DTMF信號的時間間隔,CCITT對DTMF信號規定的指標是,傳送/接收率為每秒10個數字,即每個數字100ms。代表數字的音頻信號必須持續至少45ms,但不超過55ms。100ms內其他時間為靜音,以便區別連續的兩個按鍵信號。


Goertzel演算法
DTMF解碼即是在輸入信號中搜索出有效的行頻和列頻。計算數位信號的頻譜可以採用DFT及其快速演算法FFT,而在實現DTMF解碼時,採用Goertzel演算法要比FFT更快。通過FFT可以計算得到信號所有譜線,瞭解信號整個頻域資訊,而對於DTMF信號只用關心其8個行頻/列頻及其二次諧波資訊即可(二次諧波的資訊用於將DTMF信號與聲音信號區別開)。此時Goertzel演算法能更加快速的在輸入信號中提取頻譜資訊。

Discrete Fourier Transform (DFT)
Fast Fourier Transform (FFT)

2008年3月27日 星期四

SIP Intro --- REFER method

REFER method

講到這個method,就開始有點複雜了!

因為要有以前講過的觀念,然後加上REFER與Subscrib的概念。整個例子的流程會很大、Msg的量也會增加很多! 但是,又因為有了之前的基礎,因此可以省略很多個Msg的說明,所以我就可以把整個REFER這個例子的流程簡化了很多!

首先,REFER是用在CALL Transfer上面。以下就來說明一個例子吧,假設有A,B,C三個人,A打給B,然後HOLD B,再打給C,然後把B轉接給C。最後B與C結束通訊。

A INVITE B
A HOLD B
A INVITE C
A HOLD C
A REFER B TO C
B INVITE C
C BYE A
A BYE B
...
C BYE B (or B BYE C)

而CALL Transfer又不只一種形式,其中有兩種較為常見,一種是Attended transfer,另一種為Blind transfer。前者為轉接者(發REFER的UA),在接通兩方電話後,再做Transfer,上面的例子就是Attended transfer。而後者為先接通一方電話,再發送REFER要求對方去CALL第三方。

在此先不探討CALL Transfer的方式,我將focus在REFER這個method的使用,以及其相關概念。

下面的CALL flow是一個在Dialog外的REFER,因此其To不會有tag。而在Dialog外或內也何差異?主要差異在於在Dialog內的REFER不會有Fork的產生,但在Dialog外的REFER則允許有Fork的產生。Fork有分支的意思,在此先簡單瞭解一下,當一個Event package允許使用Fork時,就會產生數個SUBSCRIBE requests,因而就能產生multiple subscriptions,就如同分支一樣,所以才稱之為Fork。(SUBSCRIBE概念會在另一篇說明)

先來看這個session外REFER的例子。再看後面的例子的時候,可以注意一下幾個Header fields的值~

Call-ID:
CSeq:
Event:
Subscription-State:

以下是在A與B建立好通訊之後的情況


Agent A             Agent B
|                        |
|       F1 REFER         |
|----------------------->|
|    F2 202 Accepted     |
|<-----------------------|
|       F3 NOTIFY        |
|<-----------------------|
|       F4 200 OK        |
|----------------------->|
|                        |
|                        |
|                        |------->
|                        | (whatever)
|                        |<------
|                        |
|      F5 NOTIFY         |
|<-----------------------|
|      F6 200 OK         |
|----------------------->|
|                        |
|                        |


Message One (F1)
REFER sip:b@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agenta.atlanta.example.com;branch=z9hG4bK2293940223
To:
From: ;tag=193402342
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 93809823 REFER
Max-Forwards: 70
Refer-To: (whatever URI)
Contact: sip:a@atlanta.example.com
Content-Length: 0


Message Two (F2)
SIP/2.0 202 Accepted
Via: SIP/2.0/UDP agenta.atlanta.example.com;branch=z9hG4bK2293940223
To: ;tag=4992881234
From: ;tag=193402342
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 93809823 REFER
Contact: sip:b@atlanta.example.com
Content-Length: 0


Message Three (F3)
NOTIFY sip:a@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9922ef992-25
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993402 NOTIFY
Max-Forwards: 70
Event: refer
Subscription-State: active;expires=(depends on Refer-To URI)
Contact: sip:b@atlanta.example.com
Content-Type: message/sipfrag;version=2.0
Content-Length: 20
SIP/2.0 100 Trying


Message Four (F4)
SIP/2.0 200 OK
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9922ef992-25
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993402 NOTIFY
Contact: sip:a@atlanta.example.com
Content-Length: 0


Message Five (F5)
NOTIFY sip:a@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9323394234
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993403 NOTIFY
Max-Forwards: 70
Event: refer
Subscription-State: terminated;reason=noresource
Contact: sip:b@atlanta.example.com
Content-Type: message/sipfrag;version=2.0
Content-Length: 16
SIP/2.0 200 OK


Message Six (F6)
SIP/2.0 200 OK
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9323394234
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993403 NOTIFY
Contact: sip:a@atlanta.example.com
Content-Length: 0



以下為接續上面的例子,情況為在A在現有的Dialog裡,發送第二次REFER。(第一次REFER是在Dialog外)


Agent A               Agent B
|                        |
|       F7 REFER         |
|----------------------->|
|    F8 202 Accepted     |
|<-----------------------|
|       F9 NOTIFY        |
|<-----------------------|
|      F10 200 OK        |
|----------------------->|
|                        |------->
|                        | (something different)
|                        |<------
|                        |
|       F11 NOTIFY       |
|<-----------------------|
|       F12 200 OK       |
|----------------------->|
|                        |
|                        |


Message Seven (F7)
REFER sip:b@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agenta.atlanta.example.com;branch=z9hG4bK9390399231
To: ;tag=4992881234
From: ;tag=193402342
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 93809824 REFER
Max-Forwards: 70
Refer-To: (some different URI)
Contact: sip:a@atlanta.example.com
Content-Length: 0


Message Eight (F8)
SIP/2.0 202 Accepted
Via: SIP/2.0/UDP agenta.atlanta.example.com;branch=z9hG4bK9390399231
To: ;tag=4992881234
From: ;tag=193402342
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 93809824 REFER
Contact: sip:b@atlanta.example.com
Content-Length: 0


Message Nine (F9)
NOTIFY sip:a@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9320394238995
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993404 NOTIFY
Max-Forwards: 70
Event: refer;id=93809824
Subscription-State: active;expires=(depends on Refer-To URI)
Contact: sip:b@atlanta.example.com
Content-Type: message/sipfrag;version=2.0
Content-Length: 20
SIP/2.0 100 Trying


Message Ten (F10)
SIP/2.0 200 OK
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK9320394238995
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993404 NOTIFY
Contact: sip:a@atlanta.example.com
Content-Length: 0


Message Eleven (F11)
NOTIFY sip:a@atlanta.example.com SIP/2.0
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK2994a93eb-fe
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993405 NOTIFY
Max-Forwards: 70
Event: refer;id=93809824
Subscription-State: terminated;reason=noresource
Contact: sip:b@atlanta.example.com
Content-Type: message/sipfrag;version=2.0
Content-Length: 16
SIP/2.0 200 OK


Message Twelve (F12)
SIP/2.0 200 OK
Via: SIP/2.0/UDP agentb.atlanta.example.com;branch=z9hG4bK2994a93eb-fe
To: ;tag=193402342
From: ;tag=4992881234
Call-ID: 898234234@agenta.atlanta.example.com
CSeq: 1993405 NOTIFY
Contact: sip:a@atlanta.example.com
Content-Length: 0

2008年3月26日 星期三

SIP Intro --- CANCEL method

CANCEL method的介紹

本節將會介紹CANCEL這個method,因為最近有focus這部分。

這個例子之前有說過

Alice                     Bob
|                        |
|       INVITE F1        |
|----------------------->|
|    180 Ringing F2      |
|<-----------------------|
|                        |
|       200 OK F3        |
|<-----------------------|
|         ACK F4         |
|----------------------->|
|   Both Way RTP Media   |
|<======================>|
|                        |
|         BYE F5         |
|<-----------------------|
|       200 OK F6        |
|----------------------->|
|                        |


我將以這個為基礎,說明CANCEL這個method的用法。首先,CANCEL的用途在於取消掉某一個REQUEST(就如這個例子的INVITE),而使用時有一個前提,就是要在RESPONSE之前送出,也就是說如果已經收到RESPONSE(2XX),則不能送CANCEL了,只能送BYE。而且要接收到Provisional response後才能送CANCEL。

OK,有了傳送的條件後,再來說CANCEL要有什麼內容限制。Request-URI、Call-ID、To、CSeq的數字部分、From(也包含了其tags)必須要跟要取消掉的REQUEST的內容一致,還有Via裡只能有一個值,這個值只能是打算要取消掉的REQUEST的Via中第一筆數據。這個內容限制就是用來找出妳要CANCEL的REQUEST(transaction)。如果沒有符合以上內容,則收到CANCEL的User Agent無法找到對應的transaction(call),UA就會回覆一個481 Call/Transaction does not exist。

符合有了以上的規範,才能正確的cancel掉妳想要cancel的request,UA就會回覆一個487 Request terminated!

成功CANCEL就會如下

Alice                      Bob
|                           |
|         INVITE F1         |
|-------------------------->|
|      180 Ringing F2       |
|<--------------------------|
|         CANCEL F3         |
|-------------------------->|
| 487 Request terminated F4 |
|<--------------------------|
|           ACK F5          |
|-------------------------->|



不成功的會像下面這樣子

Alice                         Bob
|                           |
|         INVITE F1         |
|-------------------------->|
|      180 Ringing F2       |
|<--------------------------|
|         CANCEL F3         |
|-------------------------->|
|   481 Call not exist F4   |(Call/Transaction 
|<--------------------------|  does not exist)
|           ACK F5          |
|-------------------------->|


以下是用Etherea抓的INVITE與CANCEL,可以參考對照一下。



2008年3月20日 星期四

SIP之閒言閒語 (part 2)

SIP之閒言閒語 (part 2)

簡單說明怎麼玩SIP


首先先裝個JRE(去SUN網站下載,免費的)
安裝很容易,執行~按確定就對了~

在來裝OnDo SIP server(裝JRE就是為了他)
安裝方式也是執行~按確定就對了~

安裝完後,在你的程式集裡會有他的程式捷徑,裡面有一個叫做"Brekeke SIP Server Admintool",這個是ㄧ個連結,他會用IE開啟,並進入管理者登入畫面(帳號/密碼預設為sa/sa)。

登入後,有很多設定!包含伺服器的、SIP的等等。(先別急著動,等你的softphone裝好,測試能打後再來玩!)

接著裝softphone,應該也是執行~按確定就是了!

最後按裝Ethereal(安裝我的版本,要在安裝WinCap,應該有版本出來,或許就不這樣裝兩個了)

在來怎麼玩呢?先設定好softphone的註冊設定

在箭頭地方按右鍵


按下add,新增一個SIP帳號


填入資料(填這一頁資料即可)


此時就會出現你的帳號了,記得要勾起來


如此就完成了設定,接下來就是測試撥號! 你可以在裝一個softphone在你同一台電腦上(或者不同台上),設定方式一樣,只是號碼要不同,就可以互打。

如果測試通話ok,那就開始抓packet。首先開啟Ethereal。

選擇圖中的按鈕


進入設定視窗,在上方選擇你要monitor的網卡


右下角,那六個選項都要選,比較常用


按下確定後,就開始抓packets了


可以在此輸入你要filter的protocol名稱,在此我們輸入sip(注意要小寫),然後apply


若覺得packets抓得夠了,就按下右邊圈起來的鈕,他就會停止,中間是用現有設定重新開始,左邊是用新的設定


在任一個封包上按右鍵,選擇在新視窗開啟...如此就可以同時比較多個packet了


SIP message則會顯示在上方圖片的藍色窗格中!
以上就完成了封包抓取的動作,可以真正開始玩SIP了,在你要打電話時,把Ethereal先開起來再打,這樣就可以抓到完整的packets。

以上閒言閒語就到此結束拉!

2008年3月19日 星期三

SIP之閒言閒語 (part 1)

SIP之閒言閒語!

寫了兩部SIP的小簡介~ (第三部正努力中...><),休息一下! 扯一點SIP別的東東~
看了那麼多的SIP內容,全都在紙上談兵! 真的不夠有趣,對吧?

那就準備一下下面的東西! 來驗證一下SIP吧!

1. SIP Soft Phone (網路上應該有不少免費版可玩~我是用eyebeam與X-Lite)
2. SIP server (我是用OnDo Brekeke這個SIP server,不錯! 申請授權就可使用,免費!)
3. Ethereal (免費! 抓packets的軟體,會依照各個protocols去parse packets~ 對於驗證、除錯很有用!!)
4.JRE (JAVA的東東...可以去SUN網站下載,我是裝1.5板)

上面的軟體都是基本必備的! (當然妳有實體的網路電話也可以用喔! 註冊到妳的SIP server後,就可以互打了!)

準備好上面的就可以開始驗證我之前說的SIP 第一二部的東西囉!!

想自己TRY這些軟體的人就看到這裡就好啦!

不會使用的人或懶得去TRY的人,就看SIP之閒言閒語 (part 2)吧!!

PS.好多東西等著我要寫...SIP第三部...SIP 閒言閒語(part 2)...還有一些軟體想分享...但是太忙了...好吧!! 一樣一樣來!

SIP Intro 第三部

SIP Intro 第三部...

最近還是忙,但還是先起個頭,這一部想介紹Registration,也是一樣從例子開始入手,再一一其內容、結構與流程,因為有了一、二部的基礎,我想在這一部會開始往旁邊發展,也就是說會牽扯比較多一點的東西。

ps.實在對一些網誌高手不好意思,本人第一次寫,而且向來超不會寫文章...還請多多指教、包含!

下面是之前的SIP Intro 一二部,有興趣的可以參考!
SIP Intro --- 第一部
SIP Intro --- 第二部(part 1)
SIP Intro --- 第二部(part 2)
SIP Intro --- 第二部 (part 3)

進入正題!

為何要REGISTER呢? 因為若不向SIP server註冊,那別人怎麼能知道你在哪裡,又怎麼跟妳通訊呢? 所以我們每個User都要向SIP server至少註冊一個號碼,如此,當別人要跟這個號碼做通訊時,才找的到位置。

而一筆(號碼)註冊的資訊,我們又稱之為Address of Record,裡面包含了IP、號碼等等資訊。而註冊的流程有如何呢?以下先來看一個例子,下面這個例子是在表示一個user要註冊一筆新的資訊的流程。

Bob               SIP Server
| |
| REGISTER F1 | (向SIP server發送一個註冊的Msg)
|-------------------->|
| 401 Unauthorized F2 | (SIP server會要求認證)
|<--------------------|
| REGISTER F3 | (重新發送一次,並加入認證資訊)
|-------------------->|
| 200 OK F4 | (若成功,則會回OK給user)
|<--------------------|
| |



F1 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
Max-Forwards: 70
From: Bob ;tag=a73kszlfl
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Contact:
Content-Length: 0


第一個packet裡

F2 401 Unauthorized SIP Server -> Bob
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
;received=192.0.2.201
From: Bob ;tag=a73kszlfl
To: Bob ;tag=1410948204
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="atlanta.example.com",qop="auth",nonce="ea9c8e88df84f1cec4341ae6cbe5a359",opaque="",stale=FALSE,algorithm=MD5
Content-Length: 0


F3 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
Max-Forwards: 70
From: Bob ;tag=ja743ks76zlflH
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 2 REGISTER
Contact:
Authorization: Digest username="bob",realm="atlanta.example.com",nonce="ea9c8e88df84f1cec4341ae6cbe5a359", opaque="",uri="sips:ss2.biloxi.example.com",response="dfe56131d1958046689d83306477ecc"
Content-Length: 0


F4 200 OK SIP Server -> Bob
SIP/2.0 200 OK
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92 ;received=192.0.2.201
From: Bob ;tag=ja743ks76zlflH
To: Bob ;tag=37GkEhwl6
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 2 REGISTER
Contact: ;expires=3600
Content-Length: 0



下一個例子,是在表示user想要對他註冊的Address of Record做更新的operation。

   Bob                        SIP Server
| |
| REGISTER F1 |
|------------------------------>|
| 200 OK F2 |
|<------------------------------|
| |


F1 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
Max-Forwards: 70
From: Bob ;tag=a73kszlfl
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Contact: mailto:bob@biloxi.example.com
Authorization: Digest username="bob",realm="atlanta.example.com",qop="auth", nonce="1cec4341ae6cbe5a359ea9c8e88df84f",opaque="",uri="sips:ss2.iloxi.example.com", response="71ba27c64bd01de719686aa4590d5824"
Content-Length: 0


F2 200 OK SIP Server -> Bob
SIP/2.0 200 OK
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201
From: Bob ;tag=a73kszlfl
To: Bob ;tag=34095828jh



再來這個例子是user要求現有的註冊資訊。
   Bob                        SIP Server
| |
| REGISTER F1 |
|------------------------------>|
| 200 OK F2 |
|<------------------------------|
| |


F1 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
Max-Forwards: 70
From: Bob ;tag=a73kszlfl
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Authorization: Digest username="bob",realm="atlanta.example.com",nonce="df84f1cec4341ae6cbe5ap359a9c8e88",opaque="",uri="sips:ss2.biloxi.example.com",response="aa7ab4678258377c6f7d4be6087e2f60"
Content-Length: 0


F2 200 OK SIP Server -> Bob
SIP/2.0 200 OK
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201



接下來這個例子是取消註冊。


   Bob                         SIP Server
| |
| REGISTER F1 |
|------------------------------>|
| 200 OK F2 |
|<------------------------------|
| |



F1 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7
Max-Forwards: 70
From: Bob ;tag=a73kszlfl
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Expires: 0
Contact: *
Authorization: Digest username="bob", realm="atlanta.example.com",nonce="88df84f1cac4341aea9c8ee6cbe5a359", opaque="",uri="sips:ss2.biloxi.example.com",response="ff0437c51696f9a76244f0cf1dbabbea"
Content-Length: 0


F2 200 OK SIP Server -> Bob
SIP/2.0 200 OK
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201
From: Bob ;tag=a73kszlfl
To: Bob ;tag=1418nmdsrf
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Content-Length: 0



最後是ㄧ個註冊不成功的例子,這只是其中之一,因為不成功的可能原因太多了,所以只列一個。

   Bob                        SIP Server
| |
| REGISTER F1 |
|------------------------------>|
| 401 Unauthorized F2 |
|<------------------------------|
| REGISTER F3 |
|------------------------------>|
| 401 Unauthorized F4 |
|<------------------------------|
| |


F1 REGISTER Bob -> SIP Server


REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201
From: Bob ;tag=a73kszlfl
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
Contact:
Content-Length: 0


F2 Unauthorized SIP Server -> Bob
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashds7;received=192.0.2.201
From: Bob ;tag=a73kszlfl
To: Bob ;tag=1410948204
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="atlanta.example.com", qop="auth",nonce="f1cec4341ae6ca9c8e88df84be55a359", opaque="", stale=FALSE, algorithm=MD5
Content-Length: 0


F3 REGISTER Bob -> SIP Server
REGISTER sips:ss2.biloxi.example.com SIP/2.0
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92
Max-Forwards: 70
From: Bob ;tag=JueHGuidj28dfga
To: Bob
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 2 REGISTER
Contact:
Authorization: Digest username="bob", realm="atlanta.example.com",nonce="f1cec4341ae6ca9c8e88df84be55a359", opaque="",
uri="sips:ss2.biloxi.example.com",
response="61f8470ceb87d7ebf508220214ed438b"
Content-Length: 0


F4 401 Unauthorized SIP Server -> Bob
SIP/2.0 401 Unauthorized
Via: SIP/2.0/TLS client.biloxi.example.com:5061;branch=z9hG4bKnashd92;received=192.0.2.201
From: Bob ;tag=JueHGuidj28dfga
To: Bob ;tag=1410948204
Call-ID: 1j9FpLxk3uxtm8tn@biloxi.example.com
CSeq: 2 REGISTER
WWW-Authenticate: Digest realm="atlanta.example.com", qop="auth",nonce="84f1c1ae6cbe5ua9c8e88dfa3ecm3459",opaque="", stale=FALSE, algorithm=MD5
Content-Length: 0




Cloud Tag (自行修改成多彩型式!!!)

籤雲選台器 (多彩的喔!)

本來我的Blog主題不是這個...只是臨時起意想改而已...><

標籤雲選台器原始出處

因為個人覺得原本顏色的效果真的有那麼點遺憾...因此就著手去看了他的code,發現有機會改成彩色的標籤雲!!

所以就開始想方式,希望能把256,256,256的RGB三維轉換成一維,才能把每篇文章的權重MAPPING進去,其實真的蠻簡單的! (我的網頁就是用彩色的標籤雲!)

再來就是在配色上要配合自己的網頁顏色的問題了。

我後來有搜尋一下好像沒人改過這樣的東西...

更改方法也是我自己想的...

不發佈出來是怕侵犯到原作者~ 不過據LVCHEN大大的回答是可以的! 我就放心了...


Mapping方式很簡單!

<採用三維->一維的方式>
怎麼做??

這是RGB(255,255,255)
權重應該是0~1 <這個應該也是可以自行設計的ㄧ個重點>
所以是RGB(0,0,0)~(255,255,255)要MAPPING到一個數值

我用的方法是"把三個數值看成一個數值"
(255,255,255)->(FF,FF,FF)->FFFFFF->16777216-1

如此一來,每個顏色都有一個數值(而不是三個數值)!
再來就把16777215乘上"你的權重"就可以了...(這部分可以自己設計,可以不僅僅只是乘上權重...可以加以變化)

再來就是怎麼再把一維MAPPING回三維...

很簡單!
FFFFFF->16777215
原本應該是6^5*15+16^4*15+16^3*15+16^2*15+16^1*15+16*15=16777215

但也可以這樣看!
FF,FF,FF
256^2*255+256*255+255=16777215

這樣一來要從右邊轉回左邊也不是難事!
只要這樣做,假如有個值為W要轉成RGB(X,Y,Z)
算法如下:
X=((W/256)/256);
Y=((W/256)%256);
Z=(W%256);

就完成了!(當然每個數值要取一次整數)

個人的心得就是"權重公式"很重要! 因為會關係到你的計算出來的色彩分佈! 這個部分真的可以好好研究~ 會有蠻多的變化!

(目前我的標籤雲應該每次都不太一樣的顏色喔!!)






2008年3月18日 星期二

X-Lite v.3.0 簡介 (SIP phone)

X

-Lite v.3.0 (SIP soft phone )


可以自己裝這個SIP softphone,並配合SIP server來打電話,主要拿來測試、抓SIP packets。以下有幾張圖,供參考。(操作很簡單! 我就不多做說明了~)

主畫面...



幾個功能鍵...(可以打兩線、轉接、保留等)



左邊video的畫面、右邊電話基本功能(電話簿、通話紀錄等)



SIP組態設定...(號碼、SIP server ip、port等)



2008年3月17日 星期一

Foobar2000免費的綠色的播放軟體(vista可用)

F

oobar 一個很好的音樂播放軟體!!!
好處如下...




Free software!
Green software! <免安裝>
Open Source!
資源消耗低!
穩定性夠! <目前用到現在沒當過>
播放mp3的品質不錯! <就拿windows media player 或winamp比較~就有差~>
[F3] 快速搜尋音樂
可自定義快捷鍵(Global or Local)
超多面板可供選擇~ <玩家自製!或是妳自己設定也ok!>
還有很多好處~ 試了就知道!

Foobar2000 0.95 beta 3 (vista compatible)

2008年3月16日 星期日

IE當掉了怎麼辦??

I

E當掉了,該怎麼辦?? 在這提供一個小方法!

1.按[CTRL]+[ALT]+[Delete],叫出工作管理員程式<若叫不出來就沒辦法了...>

2.切換到處理程序頁籤,把explorer.exe這個程序結束掉



3.按上方工具列的"檔案"->"新工作(執行)"



4.再跳出的視窗中輸入 Explorer.exe,在按下確定!!



5.此時IE就復活啦!

Window作業系統的快捷建

常用的windows的快捷鍵,應該說是組合鍵!! 如下


[window鍵]+F 可以打開一個搜尋視窗
[window鍵]+D 可以縮小所有視窗,再按一次就會打開
[window鍵]+S 可以用滑鼠框出要PrintScreen的範圍(OneNote的功能)
[window鍵]+R 可以叫出"執行..."的視窗
[window鍵]+E 可以叫出"我的電腦"的視窗
[window鍵]+L 可以迅速切換使用者
[window鍵]+TAB 可以3D的方式切換視窗(vista的功能)
Backspace 在browser按此鍵,可以回到上一頁
[alt]+左方向鍵 在browser按此組合鍵可以回到上一頁
[alt]+右方向鍵 在browser按此組合鍵可以回到下一頁
[alt]+上方向鍵 在browser按此組合鍵可以回到上一層
[alt]+[PrintScreen] 擷取當前視窗畫面
[alt]+[F4] 關閉視窗 (無視窗時,彈出關機選單)

[ctrl]+a 全選
[ctrl]+c 複製 <在DOS模式下是中止程式!>
[ctrl]+v 貼上
[ctrl]+x 剪下
[ctrl]+z 恢復上一個動作
[ctrl]+[tab] 切換頁籤
[ctrl]+s 存檔

2008年3月15日 星期六

SIP Intro --- 第二部 (part 3)

S

IP Intro 第二部,竟然拖到part 3,一定要在此節結束掉! SIP Intro 第二部 part 3將專心於各個例子的解釋與流程說明。<此篇篇幅可能會比以前的還要長一些,為了有完整概念以及與之後的章節作銜接、延續,就請大家耐心看下去吧...>

未看過SIP 第一部、第二部(part 1,2)的請至下面連結觀看...
SIP Intro --- 第一部
SIP Intro --- 第二部(part 1)
SIP Intro --- 第二部(part 2)


先用圖回顧一下例子,再接著說明第二個message。(若已遺忘,就往回複習一下吧!)

此例子的message flow...
   Alice                     Bob
| |
| INVITE F1 |
|----------------------->|
| 180 Ringing F2 |
|<-----------------------|
| |
| 200 OK F3 |
|<-----------------------|
| ACK F4 |
|----------------------->|
| Both Way RTP Media |
|<======================>|
| |
| BYE F5 |
|<-----------------------|
| 200 OK F6 |
|----------------------->|
| |


第一個message...

F1 INVITE Alice -> Bob

INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
Max-Forwards: 70
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 151
v=0
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000


再來就是第二個message

F2 180 Ringing Bob -> Alice
SIP/2.0 180 Ringing
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
From: Alice ;tag=9fxced76sl
To: Bob ;tag=8321234356
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Contact:
Content-Length: 0



第二個message,我可以看到To這個header field多加入了tag這個parameter(UAS產生並放入),以及Contact裡的SIP URI也改成Bob了,其用意在part 2也有說明,相信大家都知道,所以我們就可以看下一個message了!

F3 200 OK Bob -> Alice

SIP/2.0 200 OK
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
From: Alice ;tag=9fxced76sl
To: Bob ;tag=8321234356
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 147


這個message是Bob決定接受Alice的通訊要求後,回覆給Alice的message。在這可以注意到一點,From與To的SIP URI都沒有變,因為這是對於F1這個message(CSeq:1 INVITE)所做的回應,所以不會改變。再來看第四個message。

F4 ACK Alice -> Bob

ACK sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bd5
Max-Forwards: 70
From: Alice ;tag=9fxced76sl
To: Bob ;tag=8321234356
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 ACK
Content-Length: 0


到這裡應該沒什麼問題。
如此一來RTP(Real-time Transport Protocol)streams就建立完了,雙方就開始通話。通話一段時間後,假設Bob要結束通訊,這時就會送出下面的message。

F5 BYE Bob -> Alice

BYE sip:alice@client.atlanta.example.com SIP/2.0
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
Max-Forwards: 70
From: Bob ;tag=8321234356
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0


這裡要注意到CSeq的值仍為1,因為Bob與Alice是各自maintain自己的CSeq,所以對Bob來說,BYE是第一個request,所以值才看起來沒有變。Call-ID仍是不變,這沒問題,同一通Call,其Call-ID是不能變的,另外注意到的是From與To已經改變,因為是Bob發出的,所以From就填上Bob的SIP URI,To就填上了Alice的SIP URI(當然對應的tag也要變動囉)。(繼續看下去)

F6 200 OK Alice -> Bob

SIP/2.0 200 OK
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.201
From: Bob ;tag=8321234356
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0


看了這個message,大家一定有點熟悉,是的!跟之前的Bob傳給Alice的200 ok的message很像,差別只在於From與To對調而已。

到此,我們就完成了從最簡單的角度(兩個User Agent)去看一個session建立的流程,以及其流程中交換的資訊。以此為基礎,以下的例子就可以更容易上手了!(不囉嗦! 繼續下個例子)


     Alice        Proxy 1        Proxy 2          Bob
| | | |
| INVITE F1 | | |
|------------->| | |
| 407 F2 | | |
|<-------------| | |
| ACK F3 | | |
|------------->| | |
| INVITE F4 | | |
|------------->| INVITE F5 | |
| 100 F6 |------------->| INVITE F7 |
|<-------------| 100 F8 |------------->|
| |<-------------| |
| | | 180 F9 |
| | 180 F10 |<-------------|
| 180 F11 |<-------------| |
|<-------------| | 200 F12 |
| | 200 F13 |<-------------|
| 200 F14 |<-------------| |
|<-------------| | |
| ACK F15 | | |
|------------->| ACK F16 | |
| |------------->| ACK F17 |
| | |------------->|
| Both Way RTP Media |
|<==========================================>|
| | | BYE F18 |
| | BYE F19 |<-------------|
| BYE F20 |<-------------| |
|<-------------| | |
| 200 F21 | | |
|------------->| 00 F22 | |
| |------------->| 200 F23 |
| | |------------->|
| | | |



這個例子看似很龐大,但卻很簡單!其實只要之前的基礎都打好了,在看這個例子時,就只是多了兩個proxy server插在中間而已,實際去看這兩個proxy的行為,就會發現他們只是在做封包的forward而已。

OK,我想大家應該可以接受這樣的concept,有了這樣的concept,我想就可以更深入一點! 看看F1~F4這四個封包在做什麼(我想大家應該有發現這個地方不太一樣)。以下我先把前五個SIP message放在下面,以免佔篇幅!

F1 INVITE Alice -> Proxy 1
INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b43
Max-Forwards: 70
Route:
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 151

v=0
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F2 407 Proxy Authorization Required Proxy 1 -> Alice
SIP/2.0 407 Proxy Authorization Required
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b43
;received=192.0.2.101
From: Alice ;tag=9fxced76sl
To: Bob ;tag=3flal12sf
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 INVITE
Proxy-Authenticate: Digest realm="atlanta.example.com", qop="auth",
nonce="f84f1cec41e6cbe5aea9c8e88d359",
opaque="", stale=FALSE, algorithm=MD5
Content-Length: 0



F3 ACK Alice -> Proxy 1
ACK sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b43
Max-Forwards: 70
From: Alice ;tag=9fxced76sl
To: Bob ;tag=3flal12sf
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 ACK
Content-Length: 0



F4 INVITE Alice -> Proxy 1
INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
Max-Forwards: 70
Route:
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Proxy-Authorization: Digest username="alice",
realm="atlanta.example.com",
nonce="wf84f1ceczx41ae6cbe5aea9c8e88d359", opaque="",
uri="sip:bob@biloxi.example.com",
response="42ce3cef44b22f50c6a6071bc8"
Content-Type: application/sdp
Content-Length: 151

v=0
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F5 INVITE Proxy 1 -> Proxy 2
INVITE sip:bob@biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Max-Forwards: 69
Record-Route:
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 151

v=0
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000


我想F1這個message應該不會有疑問,問題在於F2這個message,為何proxy要送407給Alice? 原因在於這個proxy有Authorization的機制,也就是說若proxy接收到的message沒有包含Authentication的資訊(包含有Proxy-Authenticate這個header field),proxy server就會回覆一個407的message給UAC。

再來UAC就要會回一個ACK (F3)給proxy server,然後就要開始處理Authentication(目前講的都是Authorization的機制,定義於RFC2617)。

在F2這個message的Proxy-Authenticate這個header field裡,proxy server會放入兩個數值(realm,nonce),realm是他的名子,nonce是隨機產生出來的的數值。

這時UAC就要依照一個不可逆的演算法(這裡是用MD5),把realm、nonce、URI與密碼當作參數套入演算法,得出一個數值,稱之唯response,此時realm、nonce、uri與response會當作Proxy-Authorization的parameters,注意UAC並沒有把密碼也送出去給proxy server(當然proxy server也沒有把密碼傳送給UAC!),因為proxy server存有此UAC的密碼,如此才有達到認證的機制。

如同F4這個message,UAC把那四個parameters放在Proxy-Authorization這個header field裡,連同先前的INVITE的內容一起送給proxy server (F4)。

這裡要注意的是CSeq的內容,已經變為CSeq: 2 INVITE,如同先前說明的,這次的INVITE對於Alice來說已經是第二次了,所以sequence number一定要加一,否則proxy server不會裡會這個packet,因為proxy會當成是重送的packet,而不會把他當成是有Authorization的packet。 (其他header field的內容大家可以一一驗證,如此會更熟悉SIP message裡的資訊)


說了一大堆,來看看流程圖吧~ 會更清楚一點! (為了簡化一點,我把ACK message拿掉)



這樣應該有概念囉~

接下來其他的SIP message就大同小異了,如下


F6 100 Trying Proxy 1 -> Alice
SIP/2.0 100 Trying
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Content-Length: 0



F7 INVITE Proxy 2 -> Bob
INVITE sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Max-Forwards: 68
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 151

v=0
o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com
s=-
c=IN IP4 192.0.2.101
t=0 0
m=audio 49172 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F8 100 Trying Proxy 2 -> Proxy 1
SIP/2.0 100 Trying
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
From: Alice ;tag=9fxced76sl
To: Bob
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Content-Length: 0



F9 180 Ringing Bob -> Proxy 2
SIP/2.0 180 Ringing
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
;received=192.0.2.222
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
Contact:
CSeq: 2 INVITE
Content-Length: 0



F10 180 Ringing Proxy 2 -> Proxy 1
SIP/2.0 180 Ringing
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
Contact:
CSeq: 2 INVITE
Content-Length: 0



F11 180 Ringing Proxy 1 -> Alice
SIP/2.0 180 Ringing
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
Contact:
CSeq: 2 INVITE
Content-Length: 0



F12 200 OK Bob -> Proxy 2
SIP/2.0 200 OK
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
;received=192.0.2.222
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 147

v=0
o=bob 2890844527 2890844527 IN IP4 client.biloxi.example.com
s=-
c=IN IP4 192.0.2.201
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F13 200 OK Proxy 2 -> Proxy 1
SIP/2.0 200 OK
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 147

v=0
o=bob 2890844527 2890844527 IN IP4 client.biloxi.example.com
s=-
c=IN IP4 192.0.2.201
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F14 200 OK Proxy 1 -> Alice
SIP/2.0 200 OK
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9
;received=192.0.2.101
Record-Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 INVITE
Contact:
Content-Type: application/sdp
Content-Length: 147

v=0
o=bob 2890844527 2890844527 IN IP4 client.biloxi.example.com
s=-
c=IN IP4 192.0.2.201
t=0 0
m=audio 3456 RTP/AVP 0
a=rtpmap:0 PCMU/8000



F15 ACK Alice -> Proxy 1
ACK sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b76
Max-Forwards: 70
Route: ,

From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 ACK
Content-Length: 0



F16 ACK Proxy 1 -> Proxy 2
ACK sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b76
;received=192.0.2.101
Max-Forwards: 69
Route:
From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 ACK
Content-Length: 0



F17 ACK Proxy 2 -> Bob
ACK sip:bob@client.biloxi.example.com SIP/2.0
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74b76
;received=192.0.2.101
Max-Forwards: 68
From: Alice ;tag=9fxced76sl
To: Bob ;tag=314159
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 2 ACK
Content-Length: 0


這邊就開始RTP streams了,再來也是ㄧ樣,Bob結束通訊~

F18 BYE Bob -> Proxy 2
BYE sip:alice@client.atlanta.example.com SIP/2.0
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
Max-Forwards: 70
Route: ,

From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



F19 BYE Proxy 2 -> Proxy 1
BYE sip:alice@client.atlanta.example.com SIP/2.0
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.201
Max-Forwards: 69
Route:
From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



F20 BYE Proxy 1 -> Alice
BYE sip:alice@client.atlanta.example.com SIP/2.0
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
;received=192.0.2.222
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.201
Max-Forwards: 68
From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



F21 200 OK Alice -> Proxy 1
SIP/2.0 200 OK
Via: SIP/2.0/TCP ss1.atlanta.example.com:5060;branch=z9hG4bK2d4790.1
;received=192.0.2.111
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
;received=192.0.2.222
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.201
From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



F22 200 OK Proxy 1 -> Proxy 2
SIP/2.0 200 OK
Via: SIP/2.0/TCP ss2.biloxi.example.com:5060;branch=z9hG4bK721e4.1
;received=192.0.2.222
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.101
From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



F23 200 OK Proxy 2 -> Bob
SIP/2.0 200 OK
Via: SIP/2.0/TCP client.biloxi.example.com:5060;branch=z9hG4bKnashds7
;received=192.0.2.201
From: Bob ;tag=314159
To: Alice ;tag=9fxced76sl
Call-ID: 3848276298220188511@atlanta.example.com
CSeq: 1 BYE
Content-Length: 0



相信大家看到最後,已經覺得有點無聊了吧! 沒錯! 當妳覺得無聊時,大概就表示你已經了解他下一部會要做什麼事情了! (如果是看不懂而無聊...=.=,那可能要麻煩回去看一下前面幾部的文章囉~~ >__<)

或許大家有個疑問,萬一Bob所在的proxy也要authentication呢? 很簡單! 只要proxy 1把proxy 2回覆的407 message回給Alice,讓Alice在做一次上面說的流程,把對proxy 2的認證資訊再append進去即可(也就是說會有兩個Proxy-Authorization資訊。 (這個例子就部列舉了,有興趣的參考RFC3665吧~)

OK,SIP Intro 第二部到此結束!

再來會講什麼呢?
在有了一二部的基礎後,我想該是了解Registration的機制了。為何? 因為UA一定要跟server註冊,才能讓對方找的到,也才會有便利性、移動性、位置定位的功能。因為Registration跟目前所講的不十分相關,架構也不太相同,但卻需要一點基礎,所以可以跳脫出來講這部分。

<本來想在第二部講的...但不想在第二部拖太長...所以最後還是狠下心,把Registration拉出來,另開一部做說明>

Part 3 end.

2008年3月14日 星期五

SIP Intro --- 第二部 (part 2)

開個頭SIP Intro --- 第二部 (part 2)將接續 SIP Intro --- 第二部 (part 1)的介紹,開始說明Message structure的第二個section --- Message-Header。

位觀看前面兩個部分的人,可至下面連結觀看
SIP Intro --- 第一部
SIP Intro --- 第二部 (part 1)


Header fielders的format有定義在RFC3261(7.2)裡面,主要在描述field允許的格式(如:能否有空行或空格,要怎麼分隔欄位等等的規定),這裡就不說明這部分了,因為這部分蠻死的,直接參考RFC就可以了。(有參考到的RFC文件都放在我的個人空間裡,右方側邊攔)

接著進入正題!
在part 1的最後提到了一個例子,並也引出了第一個SIP message,分別如下

Alice                  Bob
|                        |
|       INVITE F1        |
|----------------------->|   (送出邀請,詢問是否參與通訊)
|     180 Ringing F2     |
|<-----------------------|   (告知邀請者,我在考慮或處理中...)
|                        |
|        200 OK F3       |   (告知邀請者,我願意接受通訊)
|<-----------------------|
|         ACK F4         |
|----------------------->|   (告知受邀者,邀請者以確認妳的意願)
|   Both Way RTP Media   |
|<======================>|   (開始通訊囉!!)
|                        |
|         BYE F5         |   (有一方要結束通訊,並告知對方)
|----------------------->|
|       200 OK F6        |
|<-----------------------|   (回應結束方的告知)
|                        |
F1 INVITE Alice -> Bob INVITE sip:bob@biloxi.example.com SIP/2.0 Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9 Max-Forwards: 70 From: Alice ;tag=9fxced76sl To: Bob Call-ID: 3848276298220188511@atlanta.example.com CSeq: 1 INVITE Contact: Content-Type: application/sdp Content-Length: 151 v=0 o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com s=- c=IN IP4 192.0.2.101 t=0 0 m=audio 49172 RTP/AVP 0 a=rtpmap:0 PCMU/8000 我們也了解first line的意思,至於第二部分的message-header,基本上在request這部分,主要有下面幾個header fields,
To
From
Call-ID
CSeq
Max-Forwards
Via
Contact
Supported
Require
ok,再來一一說明各個header field的功能,這些header fields的定義在RFC3261裡都有,以下是我節錄出重點,並且簡化一些尚未提到的概念(Dialog,Register等等),以免增加理解難度,畢竟本系列主要是介紹concepts,而不是implementation,所以並不會一開始就深入介紹。 To: 此header field是用來指出request的對象是誰,而header field的值要符合SIP(or SIP URI),或是其他URI(Uniform Resource Identifier) schemes。 From: 這個欄位用來指出發送這個request的人,這個header field也是跟To一樣格式(SIP URI),例子就看上面的message就對啦。而此header field允許使用user的名稱(如: Alice),至於tags則是一個parameter。 parameter是屬於header field底下的一個參數值,用來輔助header field不足的地方。而現在From裡的這個tags的功能是屬於"Dialog的建立"這部分,在此只先稍微提一下,request的From裡的tags和response裡的tags分別由requester和respondent產生(以下我將用requester代表一開始建立並發送request的人,即為Alice。同理,respondent則為Bob),並用以此來建立一個屬於他們(requester與respondent)的dialog ID,dialog解釋成對話框或許可以比較能了解,以上就是tags的用處(詳細說明在RFC3261 19.3裡有說明)。 Call-ID: 此ID用來是別是否屬於現在這一個通話(dialog),以這個例子來說,也就是說用來判別這個packet是否是屬於Alice與Bob這個通訊裡的packet。 CSeq: 此header field用來辨別message的順序,對於non-REGISTER的request,此sequence number有可能任意的值。 Max-Forwards: 很明顯的,這是用來限制這個request最遠只能傳送經過多少個hops,每經過一個hops就會減一。假如此header field已經為0時,卻還未到達destination,此時就會回覆一個483的response(Too Many Hops)給requester。 Via: 這個欄位提供資訊用來判斷response該往哪裡送,當request建立之初,UAC(即requester,亦即Alice)必須放入protocol anme與protocol version在此header field(分別是SIP與2.0,請看上面例子),另外此header field必須要有一個叫branch的parameter,這個parameter用來識別UAC與UAS(requester與respondent也就是Alice與Bob)所建立的transaction。所以此parameter對於每一個request是unique的(只有在兩個地方使用時是例外,CANCEL與ACK) 又碰到一個新名詞,姑且先叫解釋為一個Call好了,只是算是"狹義"的Call,這部分在後面會把Transaction、Dialog、Call`Session都做一次精確的定義,所以目前先勉強想成是一個狹義的Call。 Contact: 此header field用來指出接下來的subsequent request會是誰發的,在此例中即為Alice。另外,在REGISTER這個message裡使用時,有額外定義了幾個parameter,此部分會在介紹Registration時說明。 最後是Supported 與 Require這兩個header fields 這兩個header fields算是額外的功能延伸,可能在通訊方面有額外的支援或需求,就可以定義在此提供給對方知道。這部分因為在本篇並不是重點,而且不想把焦點分散掉,所以就不在這裡多做說明。 呼~終於一口氣把message-header中較為重要的、必須的header field帶過一遍... 有了以上的基礎後,我們來看接下來的SIP message會輕鬆很多~ 不妙,看來要延到part 3...=.= (個人不喜歡長度太長的文章...) 好吧~ Part 2 end.請接著看 SIP Intro --- 第二部 (part 3)

2008年3月13日 星期四

SketchUp 3D Model (20050313_2)

S

ketchUp 6 還真是有趣,雖然我用的SketchUp不是pro的版本,不過也很強大了啦!!

今天把SketchUp裡的工具全部拉出來! (嘿嘿~ 挑戰一下!)

拼了兩個小時,有了努力的結果(下圖),這次加了一些現成models玩一玩,也熟悉一下extend的用法,不過還不是很熟...model有時會拉壞掉....=.=,而且pull的面也確定是否是完整的一個面...

呵呵~ 一整個不熟!

再努力~

我一接觸就是從Sketchup 6接觸,算是超級新新手!不過以前就很喜歡圖學的東西~ 所以很想學會Sketchup

(希望能建一個有創意的3D Model...)



SketchUp 3D Model (20050313)

S

ketchUp 6是Google提供的免費3D model製作軟體,當然他有提供pro的付費版本,不過SketchUp 6免費版的功能感覺上就已經很不錯了!! 所以先來玩玩看。



目前正在玩SketchUp這個軟體,開始會把每次的model進度po上來...
還沒有構想,邊玩邊想拉~

下面就是用Sketchup 6弄出來的Model,有空在做一些優缺點分析! ^^

好用免費抓packet的軟體 Ethereal_0.10.14

費抓packet的軟體 Ethereal 0.10.14 & WinPcap 4.1 beta2



個人很愛用這個,因為免費、功能也不錯,而且這個Ethereal 0.10.14版本vista可用! (不過這應該不是最新版的)

裝完後還要再裝WinPcap 4.1 beta2喔!

我是用來抓SIP packet...

有需要的下載吧,Ethereal 0.10.14 & WinPcap 4.1 beta2的載點分別在下面(我的空間)

Ethereal 0.10.14

WinPcap 4.1 beta2

2008年3月11日 星期二

SIP Intro --- 第二部 (part 1)

SIP 第二部,我想以幾個examples帶出SIP的Message structure,並藉此更深入的了解SIP的運作細節,大概是這樣。此部將會以RFC3665為主要參考,RFC3216為輔(MSG structure)。因為內容真的很多,所以預計第三部將會是第二部的延續,並且會focus在Registration這個部分。

還未看過SIP第一部,可至下面連結觀看...
SIP Intro --- 第一部

(有一點要先聲名,在語句中常會穿插英文單字,因為實在翻成中文不太順,所以還多多見諒)
這篇過長了...
所以修改一下架構,SIP Intor第二部將分成兩個parts,1st part引出主題架構,2nd part從此架構下深入討論。


根據RFC3665,設定了幾個elements,如下


Element          Display Name    URI
--------------   --------------  ---------------------------
User Agent       Alice           alice@atlanta.example.com
User Agent       Bob             bob@biloxi.example.com
User Agent                      
Proxy Server                     ss1.atlanta.example.com
Proxy/Registrar                  ss2.biloxi.example.com
Proxy Server                     ss3.chicago.example.com
ALG                              alg1.atlanta.example.com


其IP依序為


Element          IP Address
--------------   -------------
User Agent       192.0.2.101
User Agent       192.0.2.201
User Agent       192.0.2.100
Proxy Server     192.0.2.111
Proxy/Registrar  192.0.2.222
Proxy Server     192.0.2.233
ALG              192.0.2.128


(User Agent在此我們設定為end-user)
以下的例子就會是依據以上設定來說明。

在第一部裡,已經有舉一個Alice想要與Bob通訊的例子,此例子為成功建立session的一個case,以下為其簡圖(取自RFC3665,右方為自己加的小註解)


Alice                  Bob
|                        |
|       INVITE F1        |
|----------------------->|   (送出邀請,詢問是否參與通訊)
|     180 Ringing F2     |
|<-----------------------|   (告知邀請者,我在考慮或處理中...)
|                        |
|        200 OK F3       |   (告知邀請者,我願意接受通訊)
|<-----------------------|
|         ACK F4         |
|----------------------->|   (告知受邀者,邀請者以確認妳的意願)
|   Both Way RTP Media   |
|<======================>|   (開始通訊囉!!)
|                        |
|         BYE F5         |   (有一方要結束通訊,並告知對方)
|----------------------->|
|       200 OK F6        |
|<-----------------------|   (回應結束方的告知)
|                        |
以上即為一個完整的session建立、通訊與結束。在此,我們來開始碰SIP封包吧! (若想要抓取SIP封包,可以用Ethereal來抓,filter設成sip即可。(Ethereal也是ㄧ個很好debug以及trace packet flow的軟體) 補充一點,圖中的F1,F2,....只是用來輔助說明是哪一個packet用的符號而已。看到此,或許已經開始有些疑問,Alice是怎麼找到Bob? 他們的通訊是用甚麼audio(video) codec? 怎麼知道對方有沒有自己的audio(video) codec? 這部分其實SIP在call setup這個階段就有偷偷在做溝通、協調了,這牽涉到RFC3264 (SDP),以後會再補充這部分(應該會再第四部或第五部說明)。 OK,第一個packet F1 INVITE Alice -> Bob INVITE sip:bob@biloxi.example.com SIP/2.0 Via: SIP/2.0/TCP client.atlanta.example.com:5060;branch=z9hG4bK74bf9 Max-Forwards: 70 From: Alice ;tag=9fxced76sl To: Bob Call-ID: 3848276298220188511@atlanta.example.com CSeq: 1 INVITE Contact: Content-Type: application/sdp Content-Length: 151 v=0 o=alice 2890844526 2890844526 IN IP4 client.atlanta.example.com s=- c=IN IP4 192.0.2.101 t=0 0 m=audio 49172 RTP/AVP 0 a=rtpmap:0 PCMU/8000 在這裡,因為SIP都有既定的格式(RFC3261裡有說明),所以內容我就不方便在做排版。好了,這裡首先碰到第一個麻煩事! 每一行代表什麼? 每一行中的keyword又代表什麼意義? 用途? 誰填的? 一堆問題開始冒出來! 因此,我們得先來看SIP的Message structure... SIP Message Structure是text-based,並且是使用UTF-8的format。在SIP Message的分類,主要分為兩類: Request 與 Response 也就是需求的要求方與回應方。而這兩類的Massage都是遵循下面的General Fomat:
generic-message = start-line
*message-header
CRLF
[ message-body ]
很簡單的format,三個部分:start-line、message-header以及optional的message-body,特別注意的是要有一個CRLF(carriage-return line-feed)也就是ㄧ個空行區分message-body與上面兩個sections。很明顯,optional的部分(message-body)是用來做功能擴充的、補充,這部分將在更後面來介紹。 第一個section ---> start-line,在SIP(RFC3261中)有定義其format,如下 start-line = Request-Line / Status-Line Request-Line的format [Request message的格式] Method Request-URI SIP-Version CRLF 在此,Method指的是Request的種類,有可能妳是要INVITE,也有可能妳是要註冊等等,都是在此欄位表明。Request-URI則是ㄧ個Identifier,含有標示requester的功能,詳細功能下面會再說明。最後兩個欄位(SIP-Version與CRLF)就不用說明了。以上為Request message第一行所要遵循的format。 針對Method,主要有下列幾種:
REGISTER
Provides a registrar service with contact address and the alias that can be used instead.
(User Agent註冊,這個部分以後會再開一個section討論)
INVITE
Call a user agent, transfer a call
(邀請對方通訊)
ACK
Confirm the call
(確認回覆)
CANCEL
End a call that hasn’t been OK’d yet.
(取消尚未回應的request)
BYE
End a call.
(結束通訊)
OPTION
Ask a user agent for its “capabilities”.
(詢問對方的通訊能力)
Status-Line的format [Response message的格式] SIP-Version Status-Code Reason-Phrase CRLF 第一個SIP-Version也就不用說明,Status-Code則是回應requester他的答覆,可能為200,也可能是180 等等。接著的欄位Reason-Phrase則是Status-Code的文字說明。如:OK、TRYING等。 針對Status-Code,SIP有下列六大分類。 1xx: Provisional – request received, continuing to process the request; (有"預先"回應的意思的status-code,也就是在真正處理結果出來前回應給requester說"我正在處理、或是其他狀態) 2xx: Success – the action was successfully received, understood, and accepted; (很明顯,處理結果的回應,有接受的意思) 3xx: Redirection – further action needs to be taken in order to complete the request; (需要再進一步處理的回應) 4xx: Client Error – the request contains bad syntax or cannot be fulfilled at this server; (有錯誤發生都定義在這個類別裡) 5xx: Server Error – the server failed to fulfill an apparently valid request; (Server-side的error) 6xx: Global Failure – the request cannot be fulfilled at any server. (任何server都無法處理的錯誤) 很好,到目前為止,我們理解了第一行的意義,再來就是message-header這部分,message-header fields真的不少,功能很多,而且並非每個header field都是必要的,所以會先大略帶過,以後再從例子再詳細說明。在2nd part中,我們將會繼續說明各個header field的功能,並真正開始介紹種種example,可以預期的,越往後面的例子,將不會著重在header field的說明,因為header fields將會在前1/3的例子中就說明完,後2/3將會看整個message flow,熟悉SIP的運作。 Part 1 end. 請接著看 SIP Intro --- 第二部 (part 2)

2008年3月10日 星期一

iGoogle 心得

i

Google
個人覺得超方便!

自訂首頁的功能超自由!
可以拉想要的資訊進你的iGoogle首頁!(如:時鐘、yam新聞、運動新聞、各地氣候、地圖(不管是urmap或googlemap)、CNN新聞、電視電影節目表、無名相簿、wiki搜尋等數百個小工具、小資訊可以讓你拉進你的iGoogle首頁!!(根本就是自己打照自己的入口網站)

額外的一個優點,他把gmail、blogger工具也整合進來,讓你在igoogle頁面就可以看你的gmail信箱有沒有新的mail、看你的blogger的網站分析狀態。

當然,google doc也不例外的整合進來!!

另外一個很大的優點! 就是沒有一堆你不太會去點的廣告~ (除非你想拉進來也可以~)

如此一來一個頁面就把你想看的新聞、訊息、mail、影片資訊、相簿資訊等等都整合在一個頁面裡!!!不用再開好幾個視窗切來切去的了...

應該是要有google帳號才能享有此整合功能~~ 大家可以試試看!!


igoogle連結





ps.最後推崇google一點,google"自由性"讓我很喜歡~! 雖然並非真的百分百自由的User Interface,但igoogle這樣的設計概念~ 個人覺得很不錯!

2008年3月9日 星期日

SIP Intro --- 第一部

第一部 SIP的介紹

我想在SIP第一部不要講太過於細節的東西,像是說SIP裡面的各個欄位的定義。這個在RFC3261裡占了一半一上的頁數,真的很繁瑣。因此,我想先建立一個概念之後,再往下探索,才比較容易了解,所以在第一部內容我會以簡潔的方式來表達。


SIP為Session Initiation Protocol的簡稱,主要定義在RFC3261裡面。首先,概略說明一下SIP是做什麼的。他是一個網路通訊協定,屬於應用層上控制的協定,主要用來maintain session,從session的creation、modification、maintenance到結束一個session,都是藉由SIP這個主架構才控制,另外再配合其他protocols來組成更完整的服務。(如SDP、RTP、RTSP等)

而一個session又是什麼?

簡單的來說,他可以是兩個end users間的voice call session,也可以是兩個或兩個以上的end users的video conference call session。而SIP就是在處理兩個end users怎麼建立通話或是視訊、怎麼建立3-way conference、怎麼轉接通話、結束通話等等的operations。是的,我們提到了phone call,SIP就是應用在網路電話上面,網路上有很多Soft phone就是用這種SIP協定來達成網路電話的功能。

實際上,我們也可以自己架設SIP server,然後透過這個SIP server來跟其他人通訊(這個部分以後有機會在介紹)。

到目前為止,大概能對於SIP的用途有個概念後,再繼續下去...

既然SIP在負責維護我們的通訊,那SIP到底做了些什麼呢?以下簡單扼要的說明他的operations。(以RFC3665中的例子做說明)

當Alice想要跟Bob做通訊,Alice會發一個邀請函(INVITE)給Bob,詢問Bob是否接受。此時Bob就會決擇是否要接受,在抉擇的同時,會發一個訊息(RINGING)給Alice,告訴Alice,他在考慮中。假設Bob決定接受他的通訊邀請,就會回復一個接受的訊息(200 OK)給Alice。此時,Alice就會回復Bob說"好,我收到你的回覆"這樣的訊息(ACK)給Bob。

此為止,一個call setup就完成了,也就是說SIP已經做好了session creation的流程。在接下去就是media session,也就是audio(或audio and video)的通訊,同樣的在media session中,SIP也是負責做maintain的工作。像是通話中想把對方電話hold住或是轉接對方電話到第三方等等。

最後當有一方要掛斷時,SIP也要做最後的maintain,讓雙方都能正常結束sesion,最後的步驟稱為Call teardown,因為是在網路上的通訊,假如沒有做call teardown,就有可能有一方不知道對方已經掛斷的情況或是其他例外情形。

以上就是ㄧ通call的流程,也是SIP要做的事情,很簡單,不過再來就要從這個基礎下往下探討..."為什麼RFC3261可以寫到2百多頁"...呵呵...Just kidding! 再來要深入一點,從phone call的case才著手了解...


以下是往後預計的內容...

Phone call case (考慮順便帶入Message structure的觀念)
Registration
Refer (or Specific event notification)

...

大概是這樣... (第一次做整理...很多不足的地方請見諒...)

目前study的進度在 SIP (Refer Method)

最近在study SIP REFER (RFC3515)這個部分...


大概會牽涉到...Session Initiation Protocol (SIP)-Specific Event Notification (RFC 3265)
...

主要方向是SIP在做Call的transfer的機制study...
所以會去深入study RFC3515 REFER這個部分,而REFER這個部分又涉及到RFC3265 (Specific Event Notification )。

就目前所了解的RFC3515,是在說明Subscriber與Notifier之間的行為模式...
當然要了解上面所說的前提是先了解RFC3261 (SIP: Session Initiation Protocol)這個doc。
整理完再來記錄...

到目前為止所po的文章,SIP方面的study還很零散,打算會先從RFC 3261開始著手整理,到時再po上來供大家參考。

2008年3月7日 星期五

Linux系統基礎指令(二)

下是我在網路上找的一些有關linux的資訊,這個部分比較乏味,我都是用到再來查...
=====================================================

常規表示式
什麼是常規表示式?

常規表示式(也稱為“regex”或“regexp”)是一種用來描述純文字模式的特殊語法。在 Linux 系統上,常規表示式通常被用來尋找純文字的模式,以及對純文字流執行“搜尋-置換”作業以及其它功能。
與 glob 的比較

當我們看到常規表示式時,您可能發現常規表示式的語法看起來與我們上一篇教學(請參閱本教學最後的“參考資料”一節中列出的“第 1 部分”)中研究的“文件名匹配替換”語法相類似。但是,不要讓它欺騙您;它們的類似性只是表面的。雖然常規表示式和文件名匹配替換模式可能看上去相類似,但是它們是根本不同的兩種類型。

簡單子串

記住那個警告,讓我們看一下最基本的常規表示式,簡單子串。為了這樣做,我們要使用 grep,它是一個掃瞄文件內容來尋找適合特定常規表示式的指令。grep 列印與常規表示式匹配的每一行,並忽略與之不匹配的每一行︰

在上面的指令中,grep 的第一個參數是一個常規表示式;第二個參數是一個文件名。grep 讀取 /etc/passwd 中的每一行並對它應用簡單子串常規表示式 bash 來尋找匹配項。如果找到一個匹配項,那麼 grep 列印出整行;否則,忽略該行。
$ grep bash /etc/passwd
operator:x:11:0:operator:/root:/bin/bash
root:x:0:0::/root:/bin/bash
ftp:x:40:1::/home/ftp:/bin/bash


在上面的指令中,grep 的第一個參數是一個常規表示式;第二個參數是一個文件名。grep 讀取 /etc/passwd 中的每一行並對它應用簡單子串常規表示式 bash 來尋找匹配項。如果找到一個匹配項,那麼 grep 列印出整行;否則,忽略該行。

理解簡單子串

一般來說,如果您正在搜尋一個子串,那麼您可以不提供任何“特殊”字元,而只是逐字地指定純文字。只有在子串包括 +、.、*、[、] 或 \(在這樣的情況下,這些字元需要用引號括起來並在它們的前面使用反斜線)才需要做特殊的事情。下面是簡單子串常規表示式幾個其它範例︰

/tmp (掃瞄尋找文字串 /tmp)
"\[box\]"(掃瞄尋找文字串 [box])
"\*funny\*"(掃瞄尋找文字串 *funny*)
"ld\.so"(掃瞄尋找文字串 ld.so)
元字元

使用常規表示式,可以利用元字元來執行比我們至今已研究過的範例複雜得多的搜尋。這些元字元中的一個是 "."(點),它與任何單個字元匹配︰

$ grep dev.hda /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2
/dev/hda2 swap swap sw 0 0
#/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1


在本範例中,文字純文字 dev.hda 沒有出現在 /etc/fstab 中的任何一行中。但是,grep 掃瞄這些行時沒有尋找文字 dev.hda 字串,而是尋找 dev.hda 模式。請記住 "." 將與任何單個字元相匹配。正如您看到的,"." 元字元在功能上等價於 glob 擴充中"?"元字元的工作原理。

使用 []

如果我們希望與比 "." 更具體一點地來匹配字元,那麼我們可以使用 [ 和 ](方括號)來指定要匹配的字元子集︰

$ grep dev.hda[12] /etc/fstab
/dev/hda1 /boot reiserfs noauto,noatime,notail 1 2
/dev/hda2 swap swap sw 0 0


正如您看到的,這個特殊語法的作用與“glob”文件名擴充中的 [] 相同。同樣,這是學習常規表示式的難點之一 ─ 這個語法與“glob ”文件名擴充語法類似,但又不盡相同,它經常給學習常規表示式的人帶來困惑。

使用 [^]

透過使 [ 後面緊跟一個 ^,您可以使方括號中的意思相反。在本例中,方括號將與未列在方括號內的任意字元匹配。同樣,請注意我們在常規表示式中使用 [^] ,而在 glob 中使用 [!] ︰

$ grep dev.hda[^12] /etc/fstab
/dev/hda3 / reiserfs noatime,ro 1 1
#/dev/hda4 /mnt/extra reiserfs noatime,rw 1 1


區別語法

注意下面一點很重要︰方括號內部的語法根本不同於常規表示式其它部分中的語法。例如,如果在方括號內放置一個 "." ,那麼它容許方括號與文字 "." 匹配,就像上面範例中的 1 和 2。比較起來,除非有 \ 作為前綴,否則方括號外面的文字 "." 被解釋為一個元字元。透過輸入如下指令,我們可以利用這一事實來列印 /etc/fstab 中包括文字串 dev.hda 的所有行的清單︰

$ grep dev[.]hda /etc/fstab


或者,我們也可以輸入︰

$ grep "dev\.hda" /etc/fstab


這兩個常規表示式都不可能與您的 /etc/fstab 文件中的任何行相匹配。

“*”元字元

某些元字元本身不匹配任何字元,但卻修改前一個字元的含義。一個這樣的元字元是 * (星號),它用來與前一個字元的零次或者多次重復出現相匹配。這裡是一些範例︰

ab*c(與 abbbbc 匹配但不與 abqc 匹配)
ab*c(與 abc 匹配但不與 abbqbbc 匹配)
ab*c(與 ac 匹配但不與 cba 匹配)
b[cq]*e(與 bqe 匹配但不與 eb 匹配)
b[cq]*e(與 bccqqe 匹配但不與 bccc 匹配)
b[cq]*e(與 bqqcce 匹配但不與 cqe 匹配)
b[cq]*e(與 bbbeee 匹配)
.*(與任何字串匹配)
foo.*(與以 foo 開始的任何字串相匹配)
ac 行與常規表示式 ab*c 相匹配,因為星號也容許前面的表達式(b)出現零次。請注意解釋 * 常規表示式元字元所用的方法與解釋 * glob 字元的方法根本不同。

行的開始和結束

我們在這裡要詳細描述的最後幾個元字元是 ^ 和 $ 元字元,它們用來分別與行的開始和結束相匹配。透過在常規表示式開始處使用一個 ^ ,您可以將您的模式“錨定”在行的開始。在下面的範例中,我們使用 ^# 常規表示式來與以 # 字元開始的任何行相匹配︰

$ grep ^# /etc/fstab
# /etc/fstab: static file system information.
#


完整行常規表示式

可以組合 ^ 和 $ 來與完整的行相匹配。例如,下面的常規表示式將與以 # 字元開始並以 "." 字元結束的行相匹配,在其中間可以有任意多個其它字元︰

$ grep '^#.*\.$' /etc/fstab
# /etc/fstab: static file system information.



在上面的範例中,我們用單引號將我們的常規表示式括起來以阻止 shell 解釋 $ 。在不使用單引號的情況下,grep 甚至沒有機會檢視 $,$ 就從我們的常規表示式上消失了。

2008年3月6日 星期四

很好用的快捷工具列RocketDuck It's Free!!

R

ocketDock

很好用的快捷工具列~ RocketDuck
以下是她的優點需求~

Features:
Minimize windows to the dock
Real-time window previews in Vista
Running application indicators
Simple drag-n-drop interface
Multi-monitor support
Supports alpha-blended PNG and ICO icons
Icons zoom and transition smoothly
Auto-hide and Popup on mouse over
Positioning and layering options
Fully customizable
Completely Portable
ObjectDock Docklet support
Compatible with MobyDock, ObjectDock, RK Launcher, and Y'z Dock skins
Runs great on slower computers
Unicode compliant
Supports many languages and can easily be translated
A friendly user base :)
And best of all... its FREE!!!

Minimum System Requirements:
Windows 2000/XP/Vista
500Mhz or faster CPU
10MB RAM free

RocketDuck下載點
在RocketDuck的首頁還有他的DEMO,可以先看看!
對於常常要開一些軟體使用的人來說,RocketDuck真的很方便。桌面就不會累積一堆捷徑...

2008年3月5日 星期三

一些有關Robots (tag) 介紹

前剛好在弄AdSense,碰到了robots的問題,找到了些文件資料,給大家參考參考。

Robots (tag) 介紹
===============================================

robots.txtRobots META tag

  我們知道,搜索引擎都有自己的“搜索機器人”(ROBOTS),並透過這些ROBOTS在網路上沿著網頁上的鏈接(一般是http和src鏈接)不斷抓取資料建立自己的資料庫。 對於網站管理者和內容提供者來說,有時候會有一些站點內容,不希望被ROBOTS抓取而公開。為了解決這個問題,ROBOTS開發界提供了兩個辦法:一個是robots.txt,另一個是The Robots META tag。
一、 robots.txt
  1、 什麼是robots.txt?
  robots.txt是一個純文本文件,透過在這個文件中聲明該網站中不想被robots訪問的部分,這樣,該網站的部分或全部內容就可以不被搜索引擎收錄了,或者指定搜索引擎隻收錄指定的內容。
  當一個搜索機器人訪問一個站點時,它會首先檢查該站點根目錄下是否存在robots.txt,如果找到,搜索機器人就會按照該文件中的內容來確定訪問的範圍,如果該文件不存在,那麼搜索機器人就沿著鏈接抓取。
  robots.txt必須放置在一個站點的根目錄下,而且檔案名稱必須全部小寫。
  網站 URL
  相應的 robots.txt的 URL
  http://www.w3.org/
  http://www.w3.org/robots.txt
  http://www.w3.org:80/
  http://www.w3.org:80/robots.txt
  http://www.w3.org:1234/
  http://www.w3.org:1234/robots.txt
  http://w3.org/
  http://w3.org/robots.txt


  2、 robots.txt的語法
  "robots.txt"文件包含一條或更多的記錄,這些記錄透過空行分開(以CR,CR/NL, or NL作為結束符),每一條記錄的格式如下所示:
  ":"。
  在該文件中可以使用#進行註解,具體使用方法和UNIX中的慣例一樣。該文件中的記錄通常以一行或多行User-agent開始,後面加上若幹Disallow行,詳細情況如下:
  User-agent:
  該項的值用於描述搜索引擎robot的名字,在"robots.txt"文件中,如果有多條User-agent記錄說明有多個robot會受到該協議的限制,對該文件來說,至少要有一條User-agent記錄。如果該項的值設為*,則該協議對任何機器人均有效,在"robots.txt"文件中, "User-agent:*"這樣的記錄只能有一條。
  Disallow :
  該項的值用於描述不希望被訪問到的一個URL,這個URL可以是一條完整的路徑,也可以是部分的,任何以Disallow 開頭的URL均不會被robot訪問到。例如"Disallow: /help"對/help.html 和/help/index.html都不允許搜索引擎訪問,而"Disallow: /help/"則允許robot訪問/help.html,而不能訪問/help/index.html。
  任何一條Disallow記錄為空,說明該網站的所有部分都允許被訪問,在"/robots.txt"文件中,至少要有一條Disallow記錄。如果 "/robots.txt"是一個空文件,則對於所有的搜索引擎robot,該網站都是開放的。
  下面是一些robots.txt基本的用法:
  l 禁止所有搜索引擎訪問網站的任何部分:
  User-agent: *
  Disallow: /

  l 允許所有的robot訪問
  User-agent: *
  Disallow:

  或者也可以建一個空文件 "/robots.txt" file
  l 禁止所有搜索引擎訪問網站的幾個部分(下例中的cgi-bin、tmp、private目錄)
  User-agent: *
  Disallow: /cgi-bin/
  Disallow: /tmp/
  Disallow: /private/

  l 禁止某個搜索引擎的訪問(下例中的BadBot)
  User-agent: BadBot
  Disallow: /

  l 只允許某個搜索引擎的訪問(下例中的WebCrawler)
  User-agent: WebCrawler
  Disallow:
  User-agent: *
  Disallow: /

  3、 常見搜索引擎機器人Robots名字
  名稱 搜索引擎
  Baiduspiderhttp://www.baidu.com
  Scooterhttp://www.altavista.com
  ia_archiverhttp://www.alexa.com
  Googlebothttp://www.google.com
  FAST-WebCrawlerhttp://www.alltheweb.com
  Slurphttp://www.inktomi.com
  MSNBOThttp://search.msn.com

  4、 robots.txt舉例
  下面是一些著名站點的robots.txt:
  http://www.cnn.com/robots.txt
  http://www.google.com/robots.txt
  http://www.ibm.com/robots.txt
  http://www.sun.com/robots.txt
  http://www.eachnet.com/robots.txt


  下面一個小工具專門檢查robots.txt文件的有效性:
  http://www.searchengineworld.com/cgi-bin/robotcheck.cgi


  二、 Robots META tag
  1、什麼是Robots META tag
  Robots.txt文件主要是限制整個站點或者目錄的搜索引擎訪問情況,而Robots META tag則主要是針對一個個具體的頁面。和其他的META標簽(如使用的語言、頁面的描述、關鍵詞等)一樣,Robots META tag也是放在頁面的中,專門用來告訴搜索引擎ROBOTS如何抓取該頁的內容。具體的形式類似(見黑體部分):

<html>
<head>
<title>時代營銷--網路營銷專業門戶</title>
<meta name="Robots" content="index,follow">
<meta http-equiv="Content-Type" CONTENT="text/html; charset=gb2312">
<meta name="keywords" content="營銷… ">
<meta name="description" content="時代營銷網是…">
<link rel="stylesheet" href="/public/css.css" type="text/css">
</head>

<body>

</body>

</html>

  
  2、Robots META tag的寫法:
  Robots META標簽中沒有大小寫之分,name=”Robots”表示所有的搜索引擎,可以針對某個具體搜索引擎寫為name=”BaiduSpider”。content部分有四個指令選項:index、noindex、follow、nofollow,指令間以“,”分隔。
  INDEX 指令告訴搜索機器人抓取該頁面;
  FOLLOW 指令表示搜索機器人可以沿著該頁面上的鏈接繼續抓取下去;
  Robots Meta tag的值是INDEX和FOLLOW,只有inktomi除外,對於它,值是INDEX,NOFOLLOW。
  
其中
<meta content="INDEX,FOLLOW" name="ROBOTS">
可以寫成
<meta content="ALL" name="ROBOTS">;

<meta content="NOINDEX,NOFOLLOW" name="ROBOTS">
可以寫成
<meta content="NONE" name="ROBOTS">
  要注意的是:上述的robots.txt和Robots META tag限制搜索引擎機器人(ROBOTS)抓取站點內容的辦法只是一種規則,需要搜索引擎機器人的配合才行,並不是每個ROBOTS都遵守的。

搜尋此網誌