oSIP协议栈浅析

    技术2022-05-11  66

    全文下载连接(不保证永久有效):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 meeting      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/

    最新回复(0)