oSIP协议栈浅析

来源:互联网 发布:中国宏观经济数据 编辑:程序博客网 时间:2024/04/30 01:57

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

 

oSIP协议栈浅析
 
 
1. oSIP介绍... 1
2. oSIP结构分析... 1
2.1 oSIP结构... 1
2.2 状态机(Finite State Machines)模块... 2
2.2.1 概述... 2
2.2.2 ICT状态机... 3
2.2.3 NICT状态机... 4
2.2.4 IST状态机... 5
2.2.5 NIST状态机... 6
2.3 解析器(Parsers)模块... 7
2.3.1 SIP Parser7
2.3.2 SDP Parser9
2.3.3 URL Parser10
2.4 工具(Facilities)模块... 11
2.4.1 SDP negotiator11
2.4.2 Dialog management11
3. oSIP特点... 11
3.1 oSIP的优点... 11
3.2 oSIP的缺点... 12
4. oSIP应用结构图... 12
5. oSIP使用概述... 13
5.1 初始化oSIP. 13
5.2 注册CALL BACK函数... 13
5.3 Transaction操作... 15
6. 参考... 15
 


 
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)模块
2.3.1 SIP Parser
       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)解析处理,未注的表示目前还没有解析处理(这些被保存在字符串中,可自行处理分析),可能会在后续版本中逐步补充。
 
 
2.3.2 SDP Parser
       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()操作
 
 
2.3.3 URL Parser
    这里的URL是指SIP中的URI,URI有很多参数格式,在RFC3261中列举了一些比较例子:
   The URIs within each of the following sets are equivalent:
   sip:alice@atlanta.com;transport=TCP
   sip:alice@AtLanTa.CoM;Transport=tcp
 
   sip:carol@chicago.com
   sip:carol@chicago.com;newparam=5
   sip:carol@chicago.com;security=on
 
   sip:biloxi.com;transport=tcp;method=REGISTER?to=sip:bob@biloxi.com
   sip:biloxi.com;method=REGISTER;transport=tcp?to=sip:bob@biloxi.com
 
   sip:alice@atlanta.com?subject=project x&priority=urgent
   sip:alice@atlanta.com?priority=urgent&subject=project x
 
   The URIs within each of the following sets are not equivalent:
 
   SIP:ALICE@AtLanTa.CoM;Transport=udp             (different usernames)
   sip:alice@AtLanTa.CoM;Transport=UDP
 
   sip:bob@biloxi.com                   (can resolve to different ports)
   sip:bob@biloxi.com:5060
 
   sip:bob@biloxi.com              (can resolve to different transports)
   sip:bob@biloxi.com;transport=udp
 
   sip:bob@biloxi.com     (can resolve to different port and transports)
   sip:bob@biloxi.com:6000;transport=tcp
 
   sip:carol@chicago.com                    (different header component)
   sip:carol@chicago.com?Subject=next%20meeting
 
   sip:bob@phone21.boxesbybob.com   (even though that's what
   sip:bob@192.0.2.4                 phone21.boxesbybob.com resolves to)
 
    在oSIP中处理SIP URI有比较多的操作函数提供,主要有对host,port,username,password, scheme的get()和set(),以及对参数的初始化设置和剖析处理。详细函数名称请参考源代码中的url.h。
 
 
2.4 工具(Facilities)模块
2.4.1 SDP negotiator
       SDP协商工具(SDP negotiator)帮助end point提供协商codec等功能
 
 
2.4.2 Dialog management
    对话管理工具(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);
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 


5.3 Transaction操作
    在注册完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/
原创粉丝点击