版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、Good is good, but better carries it.精益求精,善益求善。osip源代碼框架詳解Osip協(xié)議源代碼框架詳解PreparedbyMaominghuaDate2009.09.25ReviewedbyDateApprovedbyDateRevisionHistoryVersionAuthorReviewedByCommentsIssuedDate0.1Maominghua描述osip協(xié)議棧的源代碼框架目錄TOCo1-5hzuHYPERLINKl_Toc2420904811符號及縮寫PAGEREF_Toc242090481h4HYPERLINKl_Toc2420904
2、822整體描述PAGEREF_Toc242090482h4HYPERLINKl_Toc2420904833Osip包的源代碼框架解析PAGEREF_Toc242090483h5HYPERLINKl_Toc2420904843.1osip的transaction的event的產(chǎn)生PAGEREF_Toc242090484h5HYPERLINKl_Toc2420904853.1.1定時器事件的產(chǎn)生過程PAGEREF_Toc242090485h6HYPERLINKl_Toc2420904863.1.2報文觸發(fā)的事件PAGEREF_Toc242090486h7HYPERLINKl_Toc24209048
3、73.2osip的transaction的event處理流程PAGEREF_Toc242090487h7HYPERLINKl_Toc2420904883.2.1ICT的處理流程PAGEREF_Toc242090488h8HYPERLINKl_Toc2420904893.2.2IST的處理流程PAGEREF_Toc242090489h9HYPERLINKl_Toc2420904903.2.3NICT的處理流程PAGEREF_Toc242090490h9HYPERLINKl_Toc2420904913.2.4NIST的處理流程PAGEREF_Toc242090491h9HYPERLINKl_Toc
4、2420904923.3Osip報文的解析PAGEREF_Toc242090492h10HYPERLINKl_Toc2420904933.3.1sip協(xié)議報文的解析整理流程PAGEREF_Toc242090493h10HYPERLINKl_Toc2420904943.3.2Osip報文頭的解析PAGEREF_Toc242090494h12HYPERLINKl_Toc2420904953.3.3uri的解析PAGEREF_Toc242090495h14HYPERLINKl_Toc2420904963.3.4添加一個新的協(xié)議header字段PAGEREF_Toc242090496h15HYPERL
5、INKl_Toc2420904973.4osip的transaction的管理PAGEREF_Toc242090497h16HYPERLINKl_Toc2420904983.5osip中dialog的管理PAGEREF_Toc242090498h18HYPERLINKl_Toc2420904994Exosip包的源代碼框架解析PAGEREF_Toc242090499h19HYPERLINKl_Toc2420905004.1Lib庫的初始化和銷毀PAGEREF_Toc242090500h20HYPERLINKl_Toc2420905014.2Lib庫的主處理線程PAGEREF_Toc242090
6、501h23HYPERLINKl_Toc2420905024.2.12xx應(yīng)答的重發(fā)處理機制PAGEREF_Toc242090502h24HYPERLINKl_Toc2420905034.2.2Exosip_execute執(zhí)行流程PAGEREF_Toc242090503h24HYPERLINKl_Toc242090504Exosip_read_message的處理PAGEREF_Toc242090504h26HYPERLINKl_Toc242090505eXosip_process_response_out_of_transaction的處理流程:PAGEREF_Toc242090505h29
7、HYPERLINKl_Toc2420905064.2.3eXosip_automatic_action處理流程PAGEREF_Toc242090506h29HYPERLINKl_Toc2420905074.3Call的處理PAGEREF_Toc242090507h30HYPERLINKl_Toc2420905084.3.1創(chuàng)建Call的第一個INVITEPAGEREF_Toc242090508h30HYPERLINKl_Toc2420905094.3.2INVITE的ACK應(yīng)答的創(chuàng)建和發(fā)送PAGEREF_Toc242090509h32HYPERLINKl_Toc2420905104.3.3di
8、alog內(nèi)的請求的創(chuàng)建和發(fā)送PAGEREF_Toc242090510h33HYPERLINKl_Toc2420905114.3.4Dialog內(nèi)answer的創(chuàng)建和發(fā)送PAGEREF_Toc242090511h33HYPERLINKl_Toc2420905124.4Register的處理PAGEREF_Toc242090512h34HYPERLINKl_Toc2420905134.4.1向一個服務(wù)器第一次注冊PAGEREF_Toc242090513h35HYPERLINKl_Toc2420905144.4.2調(diào)整一個注冊的注冊超時時間PAGEREF_Toc242090514h35HYPERLI
9、NKl_Toc2420905154.4.3發(fā)送一個register注冊PAGEREF_Toc242090515h35Osip源代碼框架詳解符號及縮寫縮寫英文全稱中文名稱ICTInviteClientTransactionInvite類型的客戶端事務(wù)ISTInviteServerTransactionInvite類型的服務(wù)端事務(wù)NICTNotInviteClientTransaction非Invite類型的客戶端事務(wù)NISTNotInviteServerTransaction非Invite類型的服務(wù)端事務(wù)IMSIPMultimediaSubsystemIP多媒體子系統(tǒng)PSVTPacketserv
10、icevideotelephony分組域可視電話SIPSessionInitiationProtocol會話初始協(xié)議UDPUserDatagramProtocol用戶數(shù)據(jù)報協(xié)議URLUniformResourceLocator統(tǒng)一資源定位器整體描述開源代碼的osip協(xié)議棧分為兩個源代碼包,整個協(xié)議棧采用lib庫的形式,在內(nèi)部沒有使用到任務(wù),采取與TCP/IP協(xié)議棧一樣的策略,所以在使用上需要上層管理任務(wù)直接調(diào)用lib庫提供的接口。因為在Lib庫內(nèi)部沒有使用到像定時器、發(fā)送隊列等的任務(wù),而同時需要使用到定時器,所以在lib庫的內(nèi)部采用輪訓(xùn)遍歷的方式不停的檢查是否有定時器超時,這在某種程度上會浪費
11、CPU的允許時間。同時整個lib庫實現(xiàn)了對call,notify等的管理,為了實現(xiàn)重入,在應(yīng)用啟用多線程的條件下,內(nèi)部啟用的信號量和鎖的使用,在下面的分析中不涉及到信號量和鎖機制。Lib庫按照sip協(xié)議棧的層次關(guān)系分為兩個lib包,底層的osiplib包實現(xiàn)對單個請求、應(yīng)答、ACK的處理,包括message的解析、拼裝、內(nèi)容set和get,單個請求形成的transaction相關(guān)操作以及通信兩端形成的一個dialog的操作。Lib庫上層的exosiplib在底層osiplib庫的實現(xiàn)基礎(chǔ)上,實現(xiàn)對sip協(xié)議整理邏輯上的管理。Exosip主要關(guān)注的是sip協(xié)議的業(yè)務(wù)流程,包括call的整體管理,
12、notify的整體管理,publish的管理,register的管理,option的管理,refer的管理和subscription的管理,其中最主要的為call和register的管理,這兩個為sip協(xié)議棧必須實現(xiàn)的部分,另幾個功能為sip協(xié)議棧擴展部分。從這幾個業(yè)務(wù)的管理流程出發(fā),在業(yè)務(wù)的底層它們會使用到相似的一些功能,如注冊的認證,發(fā)送message,接收message,每個請求和應(yīng)答形成的transaction,多個transaction組合而成的dialog。在message的處理方面,可以分為兩類,一類為發(fā)送的message,因為是主動發(fā)送,所以上層管理層知道是什么類型的messa
13、ge,lib庫直接提供各類接口供使用。一類為接收到的message,因為不知道是哪種類型,所以需要根據(jù)解析出來的message的信息來進行處理,這部分的處理在udp.c文件中。整個lib庫的初始化在exOsip中介紹。Osip包的源代碼框架解析在osip源代碼包中最主要的包括了message的相關(guān)操作,其中最重要的為message的解析,即從獲取到的一個message中解析生成一個能夠被代碼直接處理的message數(shù)據(jù)結(jié)構(gòu)osip_message_t。與message結(jié)構(gòu)相關(guān)的操作包括根據(jù)message數(shù)據(jù)結(jié)構(gòu)的信息安裝sip協(xié)議規(guī)范組裝成一個message字符串;message結(jié)構(gòu)的初始化和
14、釋放;message結(jié)構(gòu)的拷貝操作;以及從message結(jié)構(gòu)中獲取各種已經(jīng)解析的成員變量的值和設(shè)置各個成員變量的值。在message的解析部分,除了message的頭之外,還包括了body的解析,涉及到sdp協(xié)議,包括對每個sdp字段的解析。在osip源代碼包中,設(shè)計了一個與同一個請求相關(guān)的所有message的集合transaction,在發(fā)送或接收到一個新的請求的時候就會生成一個transaction,其中ACK和CANCEL請求是比較特殊的,對于非2xx應(yīng)答的ACK和初始INVITE請求是屬于同一個transaction的,而對于2xx的請求是屬于單獨的transaction的,所以其重傳
15、操作由UAC來控制,而不在INVITE的transaction內(nèi)部進行控制。CANCEL的請求除了本身建立一個transaction外,根據(jù)協(xié)議它還會去匹配要CANCEL掉的請求的transaction,如果匹配成功會CANCEL掉相應(yīng)的transaction。在osip包中同樣設(shè)計了dialog相關(guān)操作,包括dialog的建立,dialog信息的保存,dialog的匹配及刪除等操作。其它方面,包括多線程中使用到的鎖和信號量及信號,內(nèi)部使用到的鏈表,用于事件的隊列(需要先進先出策略),一些平臺無關(guān)的封裝,定時器以及常量等的定義。這部分比較簡單,而且都是最底層函數(shù),直接封裝了系統(tǒng)調(diào)用層。osip
16、的transaction的event的產(chǎn)生transaction的狀態(tài)變化是由事件來驅(qū)動的,當transaction上有事件產(chǎn)生時,根據(jù)事件的類型和當前transaction的狀態(tài)來處理該event。Transaction上的事件分為兩類:一為定時器事件,在設(shè)定的定時器超時時會產(chǎn)生相應(yīng)的定時器事件;另一類為事件驅(qū)動事件,如發(fā)送一個請求、應(yīng)答或接收到一個請求、應(yīng)答,發(fā)送一個ACK和接收到一個ACK,即是由報文產(chǎn)生的事件。定時器事件的產(chǎn)生過程ICT、IST、NICT和NIST的定時器的事件產(chǎn)生流程都一樣,對于每一個transaction,其定時器是有順序的,ICT流程中TIMEOUT_B的優(yōu)先級最
17、高,TIMEOUT_B定時器觸發(fā)后,會觸發(fā)killtransaction的操作。當transactionff隊列中有未處理的事件時,不處理定時器,直接返回,所以在transactionff隊列中總的事件的數(shù)量是不多的。所有的定時器函數(shù)調(diào)用底層同一個定時器檢查函數(shù)_osip_transaction_need_timer_x_event。該函數(shù)會先檢查該定時器是否啟動,判斷條件為(timer-tv_sec=-1),如果啟動,檢查當前時間是否超過定時器中設(shè)定的時間,如果是,則產(chǎn)生新的定時器事件。因為定時器沒有一個單獨的任務(wù),所以是采樣輪訓(xùn)的方式檢查是否有新的定時器事件產(chǎn)生,而不是根據(jù)系統(tǒng)時鐘中斷進行
18、檢測,因此會比較占用系統(tǒng)資源。定時器的啟動和修改使用接口osip_gettimeofday和add_gettimeofday。只需要設(shè)定定時器的超時時間,即設(shè)定了一個新的定時器。取消一個定時器,只需要修改定時器的timer-tv_sev為-1。報文觸發(fā)的事件包括一個新的invite、response、ack的發(fā)送或接收,除了對非2xx的應(yīng)答ack外,其他的請求和應(yīng)答都會產(chǎn)生一個新的transaction,并且產(chǎn)生一個新的sipevent事件。osip的transaction的event處理流程在sip協(xié)議棧中為了更快更好的處理transaction,根據(jù)協(xié)議棧的描述,劃分為四種不同的trans
19、action,分別為ICT、IST、NICT和NIST。四種不同的transaction會有不同的處理流程和狀態(tài)轉(zhuǎn)換表,以及使用到不同的定時器。ICT、IST、NICT和NIST的狀態(tài)轉(zhuǎn)換采樣注冊函數(shù)處理方式,為便于管理和使用注冊函數(shù),源碼中使用了四個全局變量管理四種不同類型transaction的轉(zhuǎn)換表:ict_fsm、ist_fsm、nist_fsm和nist_fsm。osip結(jié)構(gòu)如下:structosipvoid*application_context;/*UserdefinedPointer*/*listoftransactionsforict,ist,nict,nist*/osip_
20、list_tosip_ict_transactions;/*listoficttransactions*/osip_list_tosip_ist_transactions;/*listofisttransactions*/osip_list_tosip_nict_transactions;/*listofnicttransactions*/osip_list_tosip_nist_transactions;/*300時,client端發(fā)送ACK,當重復(fù)接收到該invite的response時,重發(fā)該ACK,確保server端在killtranction前能接收到ACK。IST的處理流程同ICT
21、的處理流程,處理osip中的osip_ist_transaction鏈表。IST的相關(guān)event的注冊處理函數(shù)在ist_fsm.c文件和ist.c文件。IST使用了定時器TIMEOUT_G、TIMEOUT_H和TIMEOUT_I。使用方式與ICTL類似,詳細見協(xié)議棧說明。NICT的處理流程同ICT的處理流程,處理osip中的osip_nict_transaction鏈表。NICT的相關(guān)event的注冊處理函數(shù)在nict_fsm.c文件和nict.c文件。NICT使用了定時器TIMEOUT_E、TIMEOUT_F和TIMEOUT_K。NIST的處理流程同ICT的處理流程,處理osip中的osip
22、_nist_transaction鏈表。NIST的相關(guān)event的注冊處理函數(shù)在nist_fsm.c文件和nist.c文件。NIST使用了定時器TIMEOUT_J。Osip報文的解析sip協(xié)議報文的解析整理流程當接收到一個message的時候,需要解析該message,生成一個代碼能夠處理的數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)定義為structosip_message,該結(jié)構(gòu)定義的一個message的全部相關(guān)信息,這些信息主要是供transaction和dialog及dialog的更上一層如call,notify等的使用。對一個message的解析流程如下圖所示:在接收到一個message時,調(diào)用函數(shù)osip_m
23、essage_parse進行message的解析。首先調(diào)用函數(shù)osip_util_replace_all_lws替換掉message中的連續(xù)出現(xiàn)的rnt、rt、nt、rn、r、n為空格,message是以0為結(jié)束標志的,message的headers和body之間的分界是以rnrn為標志的,替換只替換到rnrn為止,即只替換headers部分出現(xiàn)的t、r、n。由于sip協(xié)議棧規(guī)定,每個headers都是起新行,而且新行的頭一個字符不為空格或t,所以兩個header之間的rn不會被替換掉,替換的只是一個允許multi合并項的header的內(nèi)部多個值之間的“rnt”或“rn”。舉例如下:有兩個he
24、ader,其中Subject只允許單個值出現(xiàn),Route允許有多個值出現(xiàn),而且允許分行,但是分行必須以空格或t開頭,而Subject和Route行必需頂格開始,前面是沒有空格或t的,osip_util_replace_all_lws函數(shù)將Routeheadervalue中的兩行間的rnt轉(zhuǎn)化為空格,即在邏輯上就成為一行了。Subject:LunchRoute:,一個message由三部分組成,首先是message的startline部分,該行指明這是一個sip的message,包括sip標志,請求或應(yīng)答說明,狀態(tài)值,然后以rn做為和headers的分隔符。該rn不會被osip_util_rep
25、lace_all_lws替換為空格,如請求的INVITEsip:bobSIP/2.0或應(yīng)答的SIP/2.0200OK,在三個屬性之間有且僅有一個空格。起始行的解析由_osip_message_startline_parse進行解析,解析得到message的類型,message的sipversion以及message的status_code,當status_code為初始化值0時,該message為一個請求,否則為應(yīng)答。請求的startline由_osip_message_startline_parsereq進行解析,得到請求的request_uri;應(yīng)答的startline由_osip_mes
26、sage_startline_parseresp進行解析。Startline部分的解析是嚴格安裝出現(xiàn)的三個屬性的順序進行解析的,并將解析結(jié)果保存在osip_message的結(jié)構(gòu)成員變量中。然后解析messge的headers部分,調(diào)用函數(shù)msg_headers_parse。說明見osip的header報文頭解析。如果message中在headers之后不是結(jié)束符0,則繼續(xù)解析message的負載部分,調(diào)用函數(shù)msg_osip_body_parse進行解析。Message的body解析首先查詢headers頭解析中保存的content即body的屬性:content_type,如果content
27、_type中的type不為multipart,即不支持多種mime方式的content,說明body中就一個編碼方式,直接將整個body解析為一個內(nèi)容;如果type為multitype,說明有多個編碼方式的body組合在一起形成一個整體的body,則以”-”為分隔符解析body,將body分為多個mime編碼方式的字符串,每個解析后的body內(nèi)容保存在osip_message結(jié)構(gòu)中的bodies結(jié)構(gòu)成員中。Osip報文頭的解析在解析message的header的時候,因為前面的osip_util_replace_all_lws已經(jīng)轉(zhuǎn)化了單個header內(nèi)部出現(xiàn)的r、n和t為空格,所以每個hea
28、der之間可以使用rn做為分隔符進行分隔。如果字符串開頭start_of_header已經(jīng)到達結(jié)束符”0”,則全部header解析完畢,返回成功;調(diào)用_osip_find_next_crlf找到這個header的結(jié)束字符并保存在end_of_header中;如果start_of_header為r或n,則已經(jīng)解析到rnrn即headers的結(jié)束字符串,則返回成功,并且保存start_of_header到body中,即body是從rn字符串開始解析的,所以在body解析時,需要跳過rn及之后的空格部分;根據(jù)header內(nèi)部分隔符“:”,取出header的hname和hvalue,其中hvalue在
29、某些hname的情況下是允許為空的,然后調(diào)用osip_message_set_multiple_header來解析該header的hvalue字符串;解析成功后,置start_of_header為已經(jīng)解析完的header的end_of_header,開始解析下一個header。在osip_message_set_multiple_header中,將headers分為兩類,一類如上面例子中的Subject,只允許一個值,則直接調(diào)用osip_message_set_header進行解析;一類如上面例子中的Router,允許多個值,根據(jù)sip協(xié)議,每個值之間以“,”進行分隔,所以需要查詢整個hval
30、ue字符串,根據(jù)”,”將hvalue分隔成多個值,每個值調(diào)用osip_message_set_header進行解析并保存解析結(jié)果到osip_message的數(shù)據(jù)成員變量中。因為hvalue允許使用引號將值引起來,所以需要特別處理“,”是否出現(xiàn)在引號內(nèi)部的問題。只有在引號外部的“,”才是header值的分隔符,而內(nèi)部的“,”只是一個header值的一部分。osip源碼中osip_message_set_header對于messageheaders的解析采用注冊函數(shù)的方式實現(xiàn),采用這種方式能夠在后繼版本很方便的進行新的header的添加,并且不會影響到整個源代碼的框架流程。Osip_parser_
31、cfg.c文件中定義了header頭解析所使用到的全局管理變量:static_osip_message_config_tpconfigNUMBER_OF_HEADERS;_osip_message_config_t的結(jié)構(gòu)定義如下:typedefstruct_osip_message_config_tchar*hname;int(*setheader)(osip_message_t*,constchar*);intignored_when_invalid;_osip_message_config_t;hname為sip協(xié)議定義的頭字段的字符串,這些字符串定義在osip_const.h文件中;函數(shù)
32、指針setheader為該協(xié)議header的對應(yīng)的解析函數(shù);ignored_when_invalid為是否忽略該header解析錯誤的標志,該標志值為1時,在解析該協(xié)議header發(fā)送錯誤時,忽略該錯誤,除sip協(xié)議規(guī)定的幾個必要header之外,其他頭應(yīng)該采用忽略方式。為了更快的根據(jù)header的hname,找到對應(yīng)的setheader解析函數(shù),采用了hash表的查詢方式,根據(jù)hname生成一個hash值,并且需要保證沒有兩個不同的hname對應(yīng)到同一個hash值中,以提高查詢的速度。調(diào)用_osip_message_is_known_header(hname)獲取到在數(shù)組中的index,調(diào)用
33、_osip_message_call_method(my_index,sip,hvalue)解析協(xié)議header,并且解析的結(jié)果保存在結(jié)構(gòu)osip_message_t*dest,中。每一個header都包含幾個通用的操作:header字符串的解析函數(shù),即上段講到的osip_message_set_xxx解析函數(shù);header解析后的結(jié)構(gòu)的獲取函數(shù),osip_message_get_xxx函數(shù);根據(jù)header解析后的結(jié)構(gòu)生成字符串的函數(shù):osip_xxx_str;header解析后的結(jié)構(gòu)的copy函數(shù)osip_xxx_clone;header解析后的結(jié)構(gòu)的是否函數(shù):osip_xxx_free;
34、以及header解析結(jié)構(gòu)的初始化函數(shù):osip_xxx_init。對每個header的幾個相關(guān)操作最終目的是提供協(xié)議的整個header的整體操作,包括osip_message_init,osip_message_free,osip_message_clone和osip_message_parse。uri的解析絕大部分的header的解析都是相識的,只有其中有參數(shù)的部分的header的解析會比較復(fù)雜,最主要的有from、to、contact等,因為除了本身就有參數(shù)之外,其值中的request_uri本身也可以包含有參數(shù),而這兩種參數(shù)之間是有區(qū)別的。Sip協(xié)議棧規(guī)定header的表示分為heade
35、rsname,headersvalue和headersparameter。其中name和value之間用“:”分隔,value與parameter之間用“;”分隔,parameter之間也使用“;”相分隔。在結(jié)構(gòu)定義中header的value根據(jù)具體header包含的信息進行結(jié)構(gòu)變量的定義,而如果包含parameter則直接定義一個gen_params的鏈表,所有的parameter都保存在這個鏈表中。如下面from的定義,包含有from的名稱及一個url,及相關(guān)的parameter:structosip_fromchar*displayname;/*DisplayName*/osip_uri
36、_t*url;/*url*/osip_list_tgen_params;/*otherFromparameters*/;對應(yīng)parameter的解析直接調(diào)用_osip_generic_param_parseall,該函數(shù)解析header的單個hvalue字符串中包含的所有parameter,在函數(shù)內(nèi)部會根據(jù)“;”將字符串劃分為幾個parameter,然后解析每個parameter,將解析結(jié)果保存在gen_params鏈表中。Parameter的格式為pname=pvalue類型,等號兩邊允許空格。From、to、contact以及via中間都可能出現(xiàn)url。url的解析接口為osip_uri_
37、parse,輸入為url的字符串,解析的結(jié)構(gòu)保存在結(jié)構(gòu)osip_uri_t之中。url包含有三部分內(nèi)容:url的基本信息,url的header頭部分和url的參數(shù)部分。開始部分與header頭部分用“?”進行分隔,header頭之間用”&”進行分隔,header頭部分與參數(shù)部分用”;”進行分隔,參數(shù)之間也使用“;”進行分隔。Header部分調(diào)用函數(shù)osip_uri_parse_headers進行解析,結(jié)果保存在osip_uri_t結(jié)構(gòu)中的url_headers成員變量中;parameter部分調(diào)用函數(shù)osip_uri_parse_params進行解析,其結(jié)果保存在osip_uri_t的url_
38、params成員變量中。在from、to、contact等包含url的header中,如果url中包含parameter,則整個url必需使用“”括起來,以表示一個完整url部分。所以解析from等header時需要檢查是否包含”字符。添加一個新的協(xié)議header字段需要添加多個一個對該字段進行解析的文件,包含一個header常用到的幾個基本通用操作,如果該header有特殊的地方需要處理,需要增加相關(guān)的處理函數(shù),文件名一般定義為osip_xxx.c和osip_xxx.h需要在parser_init中注冊新的header的解析函數(shù),需要修改static_osip_message_config_
39、tpconfigNUMBER_OF_HEADERS中的NUMBER_OF_HEADERS宏值。在osip_const.h中添加新的header的宏定義,osip的相關(guān)的常量宏定義都定義在該文件在osip_message.c文件額osip_message_init函數(shù)中添加對該header相關(guān)結(jié)構(gòu)的初始化操作。在osip_message_free函數(shù)中同樣添加對該header的相關(guān)釋放操作,在osip_message_clone中添加對該header的clone相關(guān)操作。在osip_message_to_str.c文件中的_osip_message_to_str函數(shù)中添加該header轉(zhuǎn)化為st
40、ring的函數(shù)注冊。如果該header不允許重復(fù)多個出現(xiàn),即不允許multipleheader,則在osip_message_parse.c文件的osip_message_set_multiple_header函數(shù)中添加對該header的處理。在osip_message.h的頭文件中的osip_message結(jié)構(gòu)中添加對該header字段的結(jié)構(gòu)。在osip_headers.h文件中添加新的header的頭文件引用。osip的transaction的管理transaction的操作主要包括transaction的初始化、transaction的free、transaction的匹配、從trans
41、action中獲取信息和設(shè)置transaction信息。根據(jù)sip協(xié)議描述一個transaction由5個必要部分組成:from、to、topvia、call-id和cseq,這5個部分一起識別某一個transaction,如果缺少任何一部分,該transaction就會設(shè)置失敗。所以對每個部分的設(shè)置都會有一個設(shè)置函數(shù):_osip_transaction_set_topvia用于設(shè)置topvia,對于發(fā)送端topvia為自己的via,對于接收端topvia為將message轉(zhuǎn)發(fā)到自己的最后一個sip-proxy服務(wù)器,_osip_transaction_set_from用于設(shè)置message的
42、發(fā)送端,_osip_transaction_set_to用于設(shè)置message的接收端,_osip_transaction_set_call_id用于設(shè)置一個dialog的標識值,該值是隨機生成的,算法保證很長一段時間內(nèi)生成的cal_id是不相同的,_osip_transaction_set_cseq用于設(shè)置cseq值,該值在同一個dialog內(nèi)部是一直保持增長的,即同一個dialog的后面的transaction的cseq會比前面的transaction的值大,按照sip協(xié)議其初始值可以是隨機數(shù),代碼實現(xiàn)中如果是非register請求,從1開始,如果是register請求的dialog,從2
43、0開始。Transaction的初始化發(fā)生在接收到一個新的請求或發(fā)送一個請求的時候,該請求以及經(jīng)過解析成為一個可以直接使用請求信息的結(jié)構(gòu)osip_message_t。其初始化具體過程如上面所述,在設(shè)置完那5個部分后,還需要初始化event的隊列,以及根據(jù)osip_message_t的type初始化使用到的定時器結(jié)構(gòu),如ICT的ict_context。其它部分的初始化在exosip源代碼中實現(xiàn),相關(guān)的如your_instance、in_socket、out_socket和record都是未了方便exosip中對transaction的管理而設(shè)置的。Transaction中的event的相關(guān)操作在
44、如前面所述。在transaction的匹配中,根據(jù)RFC3261的最新sip協(xié)議的描述,由topvia的branch_id是否相同來匹配,如果相同,就是同一個transaction的請求和應(yīng)答及ACK,為兼容舊版本的transaction的匹配規(guī)則,同時支持根據(jù)call_id,cseq,from_tag,to_tag來匹配transaction。如下圖,為便于管理的transaction,所有的transaction保持在osip_t結(jié)構(gòu)的四條鏈表中,按照處理流程的不同分為發(fā)送出去的INVITE類型請求和應(yīng)答、其它類型請求和應(yīng)答,接收到的INVITE請求和應(yīng)答、其它請求和應(yīng)答。structos
45、ipvoid*application_context;/*UserdefinedPointer*/*listoftransactionsforict,ist,nict,nist*/osip_list_tosip_ict_transactions;/*listoficttransactions*/osip_list_tosip_ist_transactions;/*listofisttransactions*/osip_list_tosip_nict_transactions;/*listofnicttransactions*/osip_list_tosip_nist_transactions;
46、/*listofnisttransactions*/#ifdefined(HAVE_DICT_DICT_H)dict*osip_ict_hastable;/*htableoficttransactions*/dict*osip_ist_hastable;/*htableofisttransactions*/dict*osip_nict_hastable;/*htableofnicttransactions*/dict*osip_nist_hastable;/*htableofnisttransactions*/#endif;在transaction的匹配過程中,如果是發(fā)出的請求,因為本地的tr
47、ansaction都會分配一個不重復(fù)的transaction_id,所以只需要比配transaction_id即可;對于incoming的message,如果是request,則匹配branch_id或者為兼容前面版本進行transaction的比配,按照協(xié)議RFC3261的17-2-3節(jié)的方式進行匹配;如果incoming的message是response,則匹配branch_id或根據(jù)RFC3261的17-1-3節(jié)的規(guī)則進行匹配。osip中dialog的管理dialog的相關(guān)的管理操作包括dialog的初始化建立過程,dialog的銷毀free過程,以及dialog的匹配。此外dialog
48、中保存了相關(guān)的路由信息和cseq信息。Dialog結(jié)構(gòu)如下,由call_id、local_tag和remote_tag唯一確定一個dialog:structosip_dialogchar*call_id;/*Call-ID*/char*local_tag;/*localtag*/char*remote_tag;/*remotetag*/osip_list_troute_set;/*routeset*/intlocal_cseq;/*lastlocalcseq*/intremote_cseq;/*lastremotecseq*/osip_to_t*remote_uri;/*remote_uri*
49、/osip_from_t*local_uri;/*local_uri*/osip_contact_t*remote_contact_uri;/*remotecontact_uri*/intsecure;/*usesecuretransportlayer*/osip_dialog_type_ttype;/*typeofdialog(CALLEEorCALLER)*/state_tstate;/*DIALOG_EARLY|DIALOG_CONFIRMED|DIALOG_CLOSED*/void*your_instance;/*forapplicationdatareference*/;在dialo
50、g的初始化時,需要根據(jù)是client端或server端來確定dialog結(jié)構(gòu)中的call_id、local_tag和remote_tag的值。根據(jù)是client端或server端來確定dialog的type,并且設(shè)置dialog的狀態(tài)。當做為client端,并且是在接收到發(fā)出的request的response時,調(diào)用osip_dialog_init_as_uac進行初始化dialog;如果是接收到server端發(fā)送過來的request,則調(diào)用osip_dialog_init_as_uac_with_remote_request進行dialog的初始化。如果是server端,調(diào)用osip_dia
51、log_init_as_uas進行初始化dialog。在dialog的匹配時,當是client端時,調(diào)用osip_dialog_match_as_uac進行匹配。檢查接收到的response和dialog中的call_id,to_tag和from_tag是否匹配,如果全部匹配,則匹配到了該dialog。為兼容前面的版本,在dialog的to或者接收到的message的toheader沒有tag的情況下,比較dialog和message的from_uri,to_uri。如果匹配,則同樣匹配的dialog。當是server端時,調(diào)用osip_dialog_match_as_uas進行匹配。其匹配方
52、法與client端的匹配方法相同。對from_tag和to_tag的匹配處理,在transaction的匹配過程中同樣使用到。Exosip包的源代碼框架解析在exosip源代碼包中包含了提供給上層管理軟件調(diào)用的關(guān)于call、message、option、refer、register、subscription、publish和insubscription的API,這些API的實現(xiàn)都在ex開頭的c文件中。為這些接口進行服務(wù)的函數(shù),包括和osiplib庫進行通信的部分的實現(xiàn)在以j開頭的源文件中如jcall.c,其中jrequest.c和jresponse.c實現(xiàn)了request和response的m
53、essage的通用構(gòu)造實現(xiàn)。同時exosip實現(xiàn)了傳輸層的四種不同的傳輸方式供上層的sip協(xié)議棧進行選擇,分別為extl_dtls.c、extl_tcp.c、extl_tls.c和extl_udp.c,它們以注冊的方式在Lib庫啟動的時候注冊到lib庫的鉤子中。為了支持多線程間的通信,在兩個線程間采用pipe的方式進行實現(xiàn),如果沒有使用多線程,這部分源代碼在編譯時會被屏蔽掉。對接收到的message進行的邏輯處理在文件udp.c中,這部分是整個協(xié)議棧邏輯比較復(fù)雜的地方。需要根據(jù)sip協(xié)議棧的標識描述和代碼實現(xiàn)框架進行整理的把握。Lib庫的初始化和銷毀整個sip的lib庫有一個總的管理結(jié)構(gòu)str
54、uctexosip_teXosip,該全局變量在lib庫被使用之前需要初始化,初始化函數(shù)為exconf.c文件的eXosip_init函數(shù)。Exosip_t結(jié)構(gòu)如下:structeXosip_ttstructeXtl_protocol*eXtl;chartransport10;char*user_agent;eXosip_call_t*j_calls;/*mycalls*/#ifndefMINISIZEeXosip_subscribe_t*j_subscribes;/*myfriends*/eXosip_notify_t*j_notifies;/*mysusbscribers*/#endifo
55、sip_list_tj_transactions;eXosip_reg_t*j_reg;/*myregistrations*/#ifndefMINISIZEeXosip_pub_t*j_pub;/*mypublications*/#endif#ifdefOSIP_MTvoid*j_cond;void*j_mutexlock;#endifosip_t*j_osip;intj_stop_ua;#ifdefOSIP_MTvoid*j_thread;jpipe_t*j_socketctl;jpipe_t*j_socketctl_event;#endifosip_fifo_t*j_events;jaut
56、hinfo_t*authinfos;intkeep_alive;intlearn_port;#ifndefMINISIZEinthttp_port;charhttp_proxy256;charhttp_outbound_proxy256;intdontsend_101;#endifintuse_rport;charipv4_for_gateway256;charipv6_for_gateway256;#ifndefMINISIZEcharevent_package256;#endifstructeXosip_dns_cachedns_entriesMAX_EXOSIP_DNS_ENTRY;st
57、ructeXosip_account_infoaccount_entriesMAX_EXOSIP_ACCOUNT_INFO;structeXosip_http_authhttp_authsMAX_EXOSIP_HTTP_AUTH;CbSipCallbackcbsipCallback;p_access_network_info*p_a_n_i;digest_cave_response*cav_v;在該結(jié)構(gòu)中,最重要的幾個成員變量如下:intj_stop_ua;協(xié)議棧啟動和停止的控制參數(shù),當j_stop_ua為0時,lib庫啟動,為非0時,lib庫停止。eXosip_call_t*j_calls;
58、j_calls用于管理全部的通話,所有的call在這個結(jié)構(gòu)中形成一個鏈表結(jié)構(gòu)。Call結(jié)構(gòu)如下:structeXosip_call_tintc_id;eXosip_dialog_t*c_dialogs;osip_transaction_t*c_inc_tr;osip_transaction_t*c_out_tr;intc_retry;/*avoidtoomanyunsuccessfullretry*/void*external_reference;eXosip_call_t*next;eXosip_call_t*parent;其中的c_id為分配的call_id,c_dialogs為同一個ca
59、ll中的dialog的集合。c_inc_tr和c_out_tr為創(chuàng)建該call時的初始化的transaction,一個終端對于一個call不是client端就是server端,所以c_inc_tr和c_out_tr只可能有一個是有transaction的,其中有一個為NULL。eXosip_reg_t*j_reg;j_reg管理sip的注冊服務(wù),所有register相關(guān)的transaction在j_reg中形成一個鏈表。根據(jù)sip協(xié)議,新的一次的注冊必需等到前一次主次完成后才能進行,所以同一個register不會像call一樣,同時有多個transaction存在。structeXtl_pro
60、tocol*eXtl;為使用的傳輸層的協(xié)議,在exosip的初始化中需要設(shè)置,在傳輸層現(xiàn)在了4種不同的傳輸實現(xiàn)方式,它們的實現(xiàn)以一個結(jié)構(gòu)的形式存在,在exosip_t初始化時注冊到exosip全局變量的extl成員變量中。osip_list_tj_transactions;用于管理全部的刪除但是還沒有系統(tǒng)回收的transaction。這些transaction不屬于call或register或者是call、register中刪除的transaction。osip_t*j_osip;為osiplib庫的管理結(jié)構(gòu),osipLib的結(jié)構(gòu)在一個任務(wù)中也只會有一個變量存在,用于管理全部的sip協(xié)議棧中出
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年優(yōu)化版:企業(yè)生產(chǎn)制造承包協(xié)議
- 2024年個人質(zhì)押股權(quán)借款協(xié)議
- 2024年軍人配偶損害賠償協(xié)議
- 2024年升級版:股權(quán)交易對接服務(wù)協(xié)議
- web課程設(shè)計書館
- 面塑配方課程設(shè)計
- 階梯軸機械加工課程設(shè)計
- 課程設(shè)計學生檔案管理
- 2024至2030年中國鮮橙多數(shù)據(jù)監(jiān)測研究報告
- 電氣蠟燭電路的課程設(shè)計
- GB/Z 18620.1-2008圓柱齒輪檢驗實施規(guī)范第1部分:輪齒同側(cè)齒面的檢驗
- GB/T 6009-2003工業(yè)無水硫酸鈉
- GB/T 31004.1-2014聲學建筑和建筑構(gòu)件隔聲聲強法測量第1部分:實驗室測量
- GA 282-2009警用服飾領(lǐng)帶
- 2023年山東省春季高考財經(jīng)類專業(yè)知識試題
- 電子商務(wù)師2023年考試模擬試題及答案
- 四年級安全教育教案洪水來了巧逃生
- 《農(nóng)業(yè)政策法規(guī)》課件
- 三石液壓消防安全制度
- 培智學校四年級生活語文《四季花開》公開課優(yōu)質(zhì)課課課件
- 古代服飾發(fā)展史英文版課件
評論
0/150
提交評論