oSIP協議棧淺析

全文下載連接(不保證永久有效):http://u.sohu.com/download?fileid=11702529523807282 

 

oSIP協議棧淺析
 
 
 


 
1. oSIP介紹
    oSIP是按照RFC3261(SIP)和RFC2327(SDP)標準,並使用標準c編寫的一個SIP協議棧。它是一個公開源碼的免費協議棧。oSIP協議棧結構簡單而小巧,它並不提供高層的SIP會話控制的API,它主要提供一些解析SIP/SDP消息的API和事務處理的狀態機。
oSIP支持線程安全,既可以用於多線程的編程模式,也可以用於單線程的編程模式;oSIP可以用來開發User Agent,IP soft-phone和SIP Proxy等等。
oSIP目前最後版本爲V 0.9.7,不久oSIP版本將升級至oSIP2(V 1.99.7)。oSIP2主要調整了一些函數和結構名稱,以及一些頭文件的名稱、內容結構的調整,整體的構架和功能不變。
本文以下描述都基於oSIP V0.9.6版本。
 
 
2. oSIP結構分析
2.1 oSIP結構
    oSIP主要包括三大部分的內容:狀態機模塊、解析器模塊和工具模塊。
    狀態機模塊的功能
完成對某個事務(註冊過程,呼叫過程等等)狀態記錄,並在特定狀態下觸發相應的事件或回調函數。
    解析器模塊的功能
       該模塊主要完成對SIP消息結構剖析、SDP消息的結構剖析以及URI結構的剖析;
    工具模塊的功能
       該模塊提供一些SDP等處理的一些工具。
 
       oSIP的模塊結構圖如下(圖2-1):


 

SIP parser
URL parser
SDP parser
Finite
State
Machines
Dialogue Facilities
SDP negotiation
Facilities
Application
狀態機模塊
解析器模塊
工具模塊(可選項)
oSIP模塊
圖2-1 oSIP結構
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


2.2 狀態機(Finite State Machines)模塊
2.2.1 概述
    oSIP狀態機(Finite State Machines)主要分爲四類,分別爲:
Ø        ICT    -- Invite Client (outgoing) Transaction
Ø        NICT   -- Non-Invite Client (outgoing) Transaction
Ø        IST    -- Invite Server (incoming) Transaction
Ø        NIST   -- Non-Invite Server (incoming) Transaction
 


 
2.2.2 ICT狀態機
 

ICT_PRE_CALLING
ICT_COMPLETED
ICT_PROCEEDING
ICT_TERMINATED
Transaction initialization
ICT_CALLING
cb_ict_transport_error
cb_ict_invite_sent
cb_ict_invite_sent2
cb_ict_transport_error
圖 2-2: ICT State Machine
cb_ict_kill_transaction
cb_ict_transport_error
cb_ict_1xx_received
cb_ict_2xx_received
cb_ict_transport_error
cb_ict_1xx_received
cb_ict_Nxx_received
cb_ict_Nxx_received
cb_ict_3456xx_received2
cb_ict_ack_sent2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


cb_ict_xxx_xxxx
表示從一種狀態轉換到另一種狀態時將調用該回調函數
表示從一種狀態轉換到另一種狀態時不調用任何回調函數
注:
      
 
 
 
 
cb_ict_Nxx_received:其中N表示一下幾個值
       3            --     cb_ict_3xx_received
       4            --     cb_ict_4xx_received
       5            --     cb_ict_5xx_received
       6            --     cb_ict_6xx_received
 


 
2.2.3 NICT狀態機
 

NICT_PRE_TRYING
NICT_COMPLETED
NICT_PROCEEDING
NICT_TERMINATED
Transaction initialization
NICT_TRYING
cb_nict_transport_error
cb_nict_XXX_sent
cb_nict_request_sent2
cb_nict_1xx_received
圖2-3: NICT State Machine
cb_nict_Nxx_received
cb_nict_kill_transaction
cb_nict_transport_error
cb_nict_request_sent2
cb_nict_1xx_received
cb_nict_Nxx_received
cb_nict_transport_error
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


cb_nict_xxx_xxxx
表示從一種狀態轉換到另一種狀態時將調用該回調函數
表示從一種狀態轉換到另一種狀態時不調用任何回調函數
注:
 
 
 
 
cb_nict_XXX_sent:其中XXX表示一下幾種消息類型,
register  --     cb_nict_register_sent
bye         --     cb_nict_bye_sent
options  --     cb_nict_options_sent
info         --     cb_nict_info_sent
cancel    --     cb_nict_cancel_sent
notify      --     cb_nict_notify_sent
subscribe --     cb_nict_subscribe_sent
unknown --     cb_nict_unknown_sent
 
cb_nict_Nxx_received:其中N表示一下幾個值
       2            --     cb_nict_2xx_received
       3            --     cb_nict_3xx_received
       4            --     cb_nict_4xx_received
       5            --     cb_nict_5xx_received
       6            --     cb_nict_6xx_received
 
 
2.2.4 IST狀態機
 

IST_PRE_PROCEEDING
IST_CONFIRMED
IST_COMPLETED
IST_TERMINATED
Transaction initialization
IST_PROCEEDING
cb_ist_invite_received
cb_ist_Nxx_sent
圖2-4: IST State Machine
cb_ist_ack_received
cb_ist_1xx_sent
cb_ist_transport_error
cb_ist_2xx_sent
cb_ist_ack_received2
cb_ist_3456xx_sent2
cb_ist_invite_received2
cb_ist_kill_transaction
cb_ist_transport_error
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


cb_ist_xxx_xxxx
表示從一種狀態轉換到另一種狀態時將調用該回調函數
表示從一種狀態轉換到另一種狀態時不調用任何回調函數
注:
 
 
 
 
cb_ist_Nxx_sent:其中N表示一下幾個值,
3            --     cb_ist_3xx_sent
4            --     cb_ist_4xx_sent
5            --     cb_ist_5xx_sent
6            --     cb_ist_6xx_sent


 
2.2.5 NIST狀態機

NIST_PRE_TRYING
NIST_COMPLETED
NIST_PROCEEDING
NIST_TERMINATED
Transaction initialization
NIST_TRYING
cb_nist_XXX_ received
cb_nist_1xx_sent
圖2-5: NIST State Machine
cb_nist_Nxx_sent
cb_nist_kill_transaction
cb_nist_transport_error
cb_nist_1xx_sent
cb_nist_Nxx_sent
cb_nist_transport_error
cb_nist_request_received2
cb_nist_request_received2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


cb_nist_xxx_xxxx
表示從一種狀態轉換到另一種狀態時將調用該回調函數
表示從一種狀態轉換到另一種狀態時不調用任何回調函數
注:
 
 
 
 
cb_nist_XXX_ received:其中XXX表示一下幾種消息類型,
register  --     cb_nist_register_received
bye         --     cb_nist_bye_received
options  --     cb_nist_options_received
info         --     cb_nist_info_received
cancel    --     cb_nist_cancel_received
notify      --     cb_nist_notify_received
subscribe --     cb_nist_subscribe_received
unknown --     cb_nist_unknown_received
 
cb_nist_Nxx_ sent:其中N表示一下幾個值
       2            --     cb_nist_2xx_sent
       3            --     cb_nist_3xx_sent
       4            --     cb_nist_4xx_sent
       5            --     cb_nist_5xx_sent
       6            --     cb_nist_6xx_sent
 
 
2.3 解析器(Parsers)模塊
       oSIP的SIP Parser處理的SIP頭域(SIP Header fields)及其相應的操作功能列表如下:

SIP Header(頭域)
Functions(函數名稱—簡寫)
 
Accept
set(),get()
Accept-Encoding
set(),get(),init(),parse(),2char(),free(),clone()
Getelement(),setelement()
Accept-Language
set(),get()
Alert-Info
set(),get()
Allow
set(),get()
Authentication-Info
 
 
Authorization
Init(),set(),parse(),get(),getauth_type(),setauth_type(),
Getusername(),setusername(),getrealm(),setrealm(),
Getnonce(),setnonce(),geturi(),seturi(),getresponse(),
Setresponse(),getdigest(),setdigest(),getalgorithm(),
Setalgorithm(),getcnonce(),setcnonce(),getopaque(),
Setopaque(),getmessage_qop(),setmessage_qop(),
getnonce_count(),setnonce_count(),2char(),free(),
clone()
Call-ID
set(),get(),parse(),2char(),free(),clone(),getnumber(),
setnumber(),gethost(),sethost()
Call-Info
set(),get(),init(),parse(),2char(),free(),clone(),
geturi(),seturi()
Contact
set(),get(),init(),parse(),2char(),free(),clone()
Content-Disposition
set(),get(),parse()
Content-Encoding
set(),get()
Content-Language
 
 
Content-Length
set(),get(),init(),parse(),2char(),free(),clone()
Content-Type
set(),get(),init(),parse(),2char(),free(),clone()
CSeq
set(),get(),init(),parse(),2char(),free(),clone(),
getnumber(),setnumber(),getmethod(),setmethod()
Date
 
 
Error-Info
set(),get()
Expires
 
 
From
set(),get(),init(),parse(),2char(),free(),clone(),
getdisplayname(),setdisplayname(),geturl(),seturl(),
param_get(),param_parseall(),param_setvalue(),
param_getvalue(),param_getname(),param_setname(),
compare()
In-Reply-To
 
 
Max-Forwards
 
 
Min-Expires
 
 
MIME-Version
set(),get()
Organization
 
 
Priority
 
 
Proxy-Authenticate
set(),get()
Proxy-Authorization
set(),get()
Proxy-Require
 
 
Record-Route
set(),get(),init(),parse(),2char(),free()
Reply-To
 
 
Require
 
 
Retry-After
 
 
Route
set(),get(),init(),parse(),2char(),free()
Server
 
 
Subject
 
 
Supported
 
 
Timestamp
 
 
To
set(),get(),init(),parse(),2char(),free(),clone()
Unsupported
 
 
User-Agent
 
 
Via
set(),append(),get(),init(),free(),parse(),2char(),
setversion(),getversion(),setprotocol(),getprotocol(),
sethost(),gethost(),setport(),getport(),setcomment(),
getcomment(),clone()
Warning
 
 
WWW-Authenticate
Init(),set(),quoted_string_set(),token_set(),parse(),
get(),getauth_type(),setauth_type(),getrealm(),setrealm(),
getdomain(),setdomain(),getnonce(),setnonce(),getstale(),
setstale(),getopaque(),setopaque(),getalgorithm(),
setalgorithm(),getqop_options(),setqop_options(),2char(),
free(),clone()
 
       注:標示“☆”表示oSIP支持該頭域(SIP Header fields)解析處理,未注的表示目前還沒有解析處理(這些被保存在字符串中,可自行處理分析),可能會在後續版本中逐步補充。
 
 
       SDP的格式一般爲:
<type>=<value>
       type通常爲一個英文字母,其取值如下(按照RFC2327,帶“*”的表示爲可選條目):
Session description
        v= (protocol version)
        o= (owner/creator and session identifier).
        s= (session name)
        i=* (session information)
        u=* (URI of description)
        e=* (email address)
        p=* (phone number)
        c=* (connection information - not required if included in all media)
        b=* (bandwidth information)
            One or more time descriptions (see below)
        z=* (time zone adjustments)
        k=* (encryption key)
        a=* (zero or more session attribute lines)
            Zero or more media descriptions (see below)
 
Time description
        t= (time the session is active)
        r=* (zero or more repeat times)
 
Media description
        m= (media name and transport address)
        i=* (media title)
        c=* (connection information - optional if included at session-level)
        b=* (bandwidth information)
        k=* (encryption key)
        a=* (zero or more media attribute lines)
 
       在oSIP中處理的type和相應操作功能如下:

type(類型)
Functions(函數名稱—簡寫)
v
version_set(),version_get()
o
origin_set(),username_get(),sess_id_get(),
sess_version_get(),nettype_get(),addrtype_get(),
addr_get()
s
name_set(),name_get()
i
info_set(),info_get()
u
uri_set(),uri_get()
e
email_add(),email_get()
p
phone_add(),phone_get()
c
connection_add(),connection_get(),nettype_get(),
addrtype_get(),addr_get(),addr_multicast_ttl_get(),
addr_multicast_int_get()
b
bandwidth_add(),bwtype_get(),bandwidth_get()
t
time_descr_add(),start_time_get(),stop_time_get()
r
repeat_add(),repeat_get()
z
adjustments_set(),adjustments_get()
k
key_set(),keytype_get(),keydata_get()
a
attribute_add(),att_field_get(),att_value_get()
m
media_add(),media_get(),port_get(),number_of_port_get(),
proto_get(),payload_add(),payload_get(),
 
    另外,oSIP還包含對SDP包的一些基本操作[set(), get(), init(), parse(), 2char(), free(), clone()],及對各類type的init()和free()操作
 
 
    這裏的URL是指SIP中的URI,URI有很多參數格式,在RFC3261中列舉了一些比較例子:
   The URIs within each of the following sets are equivalent:
   sip:[email protected];transport=TCP
   sip:[email protected];Transport=tcp
 
   sip:[email protected];newparam=5
   sip:[email protected];security=on
 
   sip:biloxi.com;transport=tcp;method=REGISTER?to=sip:[email protected]
   sip:biloxi.com;method=REGISTER;transport=tcp?to=sip:[email protected]
 
   sip:[email protected]?subject=project x&priority=urgent
   sip:[email protected]?priority=urgent&subject=project x
 
   The URIs within each of the following sets are not equivalent:
 
   SIP:[email protected];Transport=udp             (different usernames)
   sip:[email protected];Transport=UDP
 
   sip:[email protected]                   (can resolve to different ports)
   sip:[email protected]:5060
 
   sip:[email protected]              (can resolve to different transports)
   sip:[email protected];transport=udp
 
   sip:[email protected]     (can resolve to different port and transports)
   sip:[email protected]:6000;transport=tcp
 
   sip:[email protected]                    (different header component)
   sip:[email protected]?Subject=next%20meeting
 
   sip:[email protected]   (even though that's what
   sip:[email protected]                 phone21.boxesbybob.com resolves to)
 
    在oSIP中處理SIP URI有比較多的操作函數提供,主要有對host,port,username,password, scheme的get()和set(),以及對參數的初始化設置和剖析處理。詳細函數名稱請參考源代碼中的url.h。
 
 
2.4 工具(Facilities)模塊
       SDP協商工具(SDP negotiator)幫助end point提供協商codec等功能
 
 
    對話管理工具(Dialog management)是oSIP提供的一個比較強大的輔助工具,主要用於有能力應答呼叫的end point。
    對話管理工具(Dialog management)能夠幫助記錄請求和響應消息,利用這個工具使end point能夠快速準確的作出應答。
 
 
3. oSIP特點
3.1 oSIP的優點
n        Osip沒有給開發者限定在特定的某個執行模式下,能夠使開發者選定一個比較適合自己的模式。
n        Osip的各個模塊是相對清晰、獨立的,因而去掉某個模塊時也比較容易。
n        Osip的解析器提供了較爲完善的API,包含了消息的構造、修改和產生等。
 
3.2 oSIP的缺點
¨         oSIP目前版本源代碼結構、定義比較混亂,並且缺乏文檔,閱讀比較困難;該問題將在oSIP2中得到改善。
¨         oSIP不提供任何快速產生請求消息和響應消息的方法,所有請求消息和響應消息的形成必須調用一組sip message api來手動組裝完成,關於這方面的缺陷,osip作者可能在以後會開發一個eXoSIP的API來完成。
¨         由於oSIP結構簡單,外圍相關模塊需要用戶自己開發,如SIP消息的接收和發送,RTP/RTCP的語音數據的處理等。
 
4. oSIP應用結構圖
 

Receive/Send
SIP Messages
SIP parser
URL parser
SDP parser
Finite
State
Machines
Dialogue Facilities
SDP negotiation
Facilities
 Main thread
狀態機模塊
解析器模塊
工具模塊(可選項)
oSIP模塊
圖4-1 oSIP應用
Receive/Send
RTP/RTCP
oSIP
Instance
Transaction
Context
B
A
Application
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


其中:
       ①:初始化oSIP和註冊CALL BACK函數;
       ②:添加事件A;
       ③:執行事務
       ④:取消事件A
       ⑤:解析消息
       ⑥:觸發CALL BACK函數
       ⑦:接收/發送消息
       A:保存狀態
       B:接收/發送語音包
 
 
5. oSIP使用概述
5.1 初始化oSIP
       在使用oSIP前必須先初始化oSIP,主要調用函數osip_global_init()osip_init(),具體操作代碼如下:

osip_t *osip;
 // initialise internal element first
 if (0!=osip_global_init())
   return -1;
 // allocate a global osip element.
 if (0!=osip_init(&osip))
   return -1;
 
 
 
 
 
 
 
 
 
 


5.2 註冊CALL BACK函數
       需要註冊的call back函數主要包含發送消息、結束事務、發送失敗、4個狀態機(ICT、NICT、IST、NIST)相關函數。
       註冊發送消息的CALL BACK函數:

osip_setcb_send_message(osip, &application_cb_snd_message);
 
 
 


       註冊結束事務的CALL BACK函數:

osip_setcb_ict_kill_transaction(osip,&application_cb_ict_kill_transaction);
osip_setcb_ist_kill_transaction(osip,&application_cb_ist_kill_transaction);
osip_setcb_nict_kill_transaction(osip,&application_cb_nict_kill_transaction);
osip_setcb_nist_kill_transaction(osip,&application_cb_nist_kill_transaction);
 
 
 
 
 
 


       註冊發送失敗的CALL BACK函數:
 
 

osip_setcb_ict_transport_error(osip,&application_cb_transport_error);
osip_setcb_ist_transport_error(osip,&application_cb_transport_error);
osip_setcb_nict_transport_error(osip,&application_cb_transport_error);
osip_setcb_nist_transport_error(osip,&application_cb_transport_error);
 
 
 
 
 
 


註冊ICT、NICT、IST、NIST CALL BACK函數

osip_setcb_ict_2xx_received2(osip,&application_cb_rcvresp_retransmission);
osip_setcb_ict_3456xx_received2(osip,&application_cb_rcvresp_retransmission);
osip_setcb_ict_invite_sent2(osip,&application_cb_sndreq_retransmission);
osip_setcb_ist_2xx_sent2(osip,&application_cb_sndresp_retransmission);
osip_setcb_ist_3456xx_sent2(osip,&application_cb_sndresp_retransmission);
osip_setcb_ist_invite_received2(osip,&application_cb_rcvreq_retransmission);
osip_setcb_nict_2xx_received2(osip,&application_cb_rcvresp_retransmission);
osip_setcb_nict_3456xx_received2(osip,&application_cb_rcvresp_retransmission);
osip_setcb_nict_request_sent2(osip,&application_cb_sndreq_retransmission);
osip_setcb_nist_2xx_sent2(osip,&application_cb_sndresp_retransmission);
osip_setcb_nist_3456xx_sent2(osip,&application_cb_sndresp_retransmission);
osip_setcb_nist_request_received2(osip,&application_cb_rcvreq_retransmission);
osip_setcb_ict_invite_sent (osip,&application_cb_sndinvite);
osip_setcb_ict_ack_sent     (osip,&application_cb_sndack);
osip_setcb_nict_register_sent(osip,&application_cb_sndregister);
osip_setcb_nict_bye_sent     (osip,&application_cb_sndbye);
osip_setcb_nict_cancel_sent (osip,&application_cb_sndcancel);
osip_setcb_nict_info_sent    (osip,&application_cb_sndinfo);
osip_setcb_nict_options_sent (osip,&application_cb_sndoptions);
osip_setcb_nict_subscribe_sent (osip,&application_cb_sndoptions);
osip_setcb_nict_notify_sent (osip,&application_cb_sndoptions);
osip_setcb_nict_unknown_sent(osip,&application_cb_sndunkrequest);
osip_setcb_ict_1xx_received(osip,&application_cb_rcv1xx);
osip_setcb_ict_2xx_received(osip,&application_cb_rcv2xx);
osip_setcb_ict_3xx_received(osip,&application_cb_rcv3xx);
osip_setcb_ict_4xx_received(osip,&application_cb_rcv4xx);
osip_setcb_ict_5xx_received(osip,&application_cb_rcv5xx);
osip_setcb_ict_6xx_received(osip,&application_cb_rcv6xx);
osip_setcb_ist_1xx_sent(osip,&application_cb_snd1xx);
osip_setcb_ist_2xx_sent(osip,&application_cb_snd2xx);
osip_setcb_ist_3xx_sent(osip,&application_cb_snd3xx);
osip_setcb_ist_4xx_sent(osip,&application_cb_snd4xx);
osip_setcb_ist_5xx_sent(osip,&application_cb_snd5xx);
osip_setcb_ist_6xx_sent(osip,&application_cb_snd6xx);
osip_setcb_nict_1xx_received(osip,&application_cb_rcv1xx);
osip_setcb_nict_2xx_received(osip,&application_cb_rcv2xx);
osip_setcb_nict_3xx_received(osip,&application_cb_rcv3xx);
osip_setcb_nict_4xx_received(osip,&application_cb_rcv4xx);
osip_setcb_nict_5xx_received(osip,&application_cb_rcv5xx);
osip_setcb_nict_6xx_received(osip,&application_cb_rcv6xx);
osip_setcb_nist_1xx_sent(osip,&application_cb_snd1xx);
osip_setcb_nist_2xx_sent(osip,&application_cb_snd2xx);
osip_setcb_nist_3xx_sent(osip,&application_cb_snd3xx);
osip_setcb_nist_4xx_sent(osip,&application_cb_snd4xx);
osip_setcb_nist_5xx_sent(osip,&application_cb_snd5xx);
osip_setcb_nist_6xx_sent(osip,&application_cb_snd6xx);
osip_setcb_ist_invite_received   (osip,&application_cb_rcvinvite);
osip_setcb_ist_ack_received      (osip,&application_cb_rcvack);
osip_setcb_ist_ack_received2     (osip,&application_cb_rcvack2);
osip_setcb_nist_register_received(osip,&application_cb_rcvregister);
osip_setcb_nist_bye_received     (osip,&application_cb_rcvbye);
osip_setcb_nist_cancel_received (osip,&application_cb_rcvcancel);
osip_setcb_nist_info_received    (osip,&application_cb_rcvinfo);
osip_setcb_nist_options_received (osip,&application_cb_rcvoptions);
osip_setcb_nist_subscribe_received(osip,&application_cb_rcvoptions);
osip_setcb_nist_notify_received (osip,&application_cb_rcvoptions);
osip_setcb_nist_unknown_received (osip,&application_cb_rcvunkrequest);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


    在註冊完CALL BACK函數後,應用程序可以建立Transaction來調用oSIP的解析器和狀態機模塊的操作,來實現不同應用程序的需求。
 
 
6. 參考
       [1] SIP   --        RFC3261      (http://www.ietf.org)
       [2] SDP --    RFC2327(http://www.ieft.org)
       [3] oSIP Library          --    http://www.gnu.org/software/osip/
       [4] oSIP mailing list      --    http://www.atosc.org/pipermail/public/osip/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章