osip源代碼框架詳解_第1頁
osip源代碼框架詳解_第2頁
osip源代碼框架詳解_第3頁
osip源代碼框架詳解_第4頁
osip源代碼框架詳解_第5頁
已閱讀5頁,還剩30頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Osip協(xié)議源代碼框架詳解Prepared byMao minghuaDateReviewed by DateApproved byDateRevision HistoryVersionAuthorReviewed ByCommentsIssued Date0.1Mao minghua描述osip協(xié)議棧的源代碼框架目錄 TOC o 1-5 h z u HYPERLINK l _Toc242090481 1符號及縮寫 PAGEREF _Toc242090481 h 4 HYPERLINK l _Toc242090482 2整體描述 PAGEREF _Toc242090482 h 4 HYPERL

2、INK l _Toc242090483 3Osip包的源代碼框架解析 PAGEREF _Toc242090483 h 5 HYPERLINK l _Toc242090484 3.1osip的transaction的event的產生 PAGEREF _Toc242090484 h 5 HYPERLINK l _Toc242090485 定時器事件的產生過程 PAGEREF _Toc242090485 h 6 HYPERLINK l _Toc242090486 報文觸發(fā)的事件 PAGEREF _Toc242090486 h 7 HYPERLINK l _Toc242090487 3.2osip 的

3、transaction的event處理流程 PAGEREF _Toc242090487 h 7 HYPERLINK l _Toc242090488 ICT的處理流程 PAGEREF _Toc242090488 h 8 HYPERLINK l _Toc242090489 IST的處理流程 PAGEREF _Toc242090489 h 9 HYPERLINK l _Toc242090490 NICT的處理流程 PAGEREF _Toc242090490 h 9 HYPERLINK l _Toc242090491 NIST的處理流程 PAGEREF _Toc242090491 h 9 HYPERL

4、INK l _Toc242090492 3.3Osip報文的解析 PAGEREF _Toc242090492 h 10 HYPERLINK l _Toc242090493 sip協(xié)議報文的解析整理流程 PAGEREF _Toc242090493 h 10 HYPERLINK l _Toc242090494 Osip報文頭的解析 PAGEREF _Toc242090494 h 12 HYPERLINK l _Toc242090495 uri的解析 PAGEREF _Toc242090495 h 14 HYPERLINK l _Toc242090496 添加一個新的協(xié)議header字段 PAGER

5、EF _Toc242090496 h 15 HYPERLINK l _Toc242090497 3.4osip的transaction的管理 PAGEREF _Toc242090497 h 16 HYPERLINK l _Toc242090498 3.5osip中dialog的管理 PAGEREF _Toc242090498 h 18 HYPERLINK l _Toc242090499 4Exosip包的源代碼框架解析 PAGEREF _Toc242090499 h 19 HYPERLINK l _Toc242090500 4.1Lib庫的初始化和銷毀 PAGEREF _Toc24209050

6、0 h 20 HYPERLINK l _Toc242090501 4.2Lib庫的主處理線程 PAGEREF _Toc242090501 h 23 HYPERLINK l _Toc242090502 2xx應答的重發(fā)處理機制 PAGEREF _Toc242090502 h 24 HYPERLINK l _Toc242090503 Exosip_execute執(zhí)行流程 PAGEREF _Toc242090503 h 24 HYPERLINK l _Toc242090504 Exosip_read_message的處理 PAGEREF _Toc242090504 h 26 HYPERLINK l

7、_Toc242090505 eXosip_process_response_out_of_transaction的處理流程: PAGEREF _Toc242090505 h 29 HYPERLINK l _Toc242090506 eXosip_automatic_action處理流程 PAGEREF _Toc242090506 h 29 HYPERLINK l _Toc242090507 4.3Call的處理 PAGEREF _Toc242090507 h 30 HYPERLINK l _Toc242090508 創(chuàng)建Call的第一個INVITE PAGEREF _Toc242090508

8、h 30 HYPERLINK l _Toc242090509 INVITE的ACK應答的創(chuàng)建和發(fā)送 PAGEREF _Toc242090509 h 32 HYPERLINK l _Toc242090510 dialog內的請求的創(chuàng)建和發(fā)送 PAGEREF _Toc242090510 h 33 HYPERLINK l _Toc242090511 Dialog內answer的創(chuàng)建和發(fā)送 PAGEREF _Toc242090511 h 33 HYPERLINK l _Toc242090512 4.4Register的處理 PAGEREF _Toc242090512 h 34 HYPERLINK l

9、_Toc242090513 向一個服務器第一次注冊 PAGEREF _Toc242090513 h 35 HYPERLINK l _Toc242090514 調整一個注冊的注冊超時時間 PAGEREF _Toc242090514 h 35 HYPERLINK l _Toc242090515 發(fā)送一個register注冊 PAGEREF _Toc242090515 h 35Osip源代碼框架詳解符號及縮寫縮寫英文全稱中文名稱ICTInvite Client Transaction Invite類型的客戶端事務ISTInvite Server TransactionInvite類型的服務端事務NI

10、CTNot Invite Client Transaction 非Invite類型的客戶端事務NISTNot Invite Server Transaction非Invite類型的服務端事務IMSIP Multimedia SubsystemIP多媒體子系統(tǒng)PSVTPacket service video telephony分組域可視電話SIPSession Initiation Protocol會話初始協(xié)議UDPUser Datagram Protocol用戶數據報協(xié)議URLUniform Resource Locator統(tǒng)一資源定位器整體描述開源代碼的osip協(xié)議棧分為兩個源代碼包,整個協(xié)

11、議棧采用lib庫的形式,在內部沒有使用到任務,采取與TCP/IP協(xié)議棧一樣的策略,所以在使用上需要上層管理任務直接調用lib庫提供的接口。因為在Lib庫內部沒有使用到像定時器、發(fā)送隊列等的任務,而同時需要使用到定時器,所以在lib庫的內部采用輪訓遍歷的方式不停的檢查是否有定時器超時,這在某種程度上會浪費CPU的允許時間。同時整個lib庫實現了對call, notify等的管理,為了實現重入,在應用啟用多線程的條件下,內部啟用的信號量和鎖的使用,在下面的分析中不涉及到信號量和鎖機制。Lib庫按照sip協(xié)議棧的層次關系分為兩個lib包,底層的osip lib包實現對單個請求、應答、ACK的處理,包

12、括message的解析、拼裝、內容set和get,單個請求形成的transaction相關操作以及通信兩端形成的一個dialog的操作。Lib庫上層的exosip lib在底層osip lib庫的實現基礎上,實現對sip協(xié)議整理邏輯上的管理。Exosip主要關注的是sip協(xié)議的業(yè)務流程,包括call的整體管理,notify的整體管理, publish的管理,register的管理,option的管理,refer的管理和subscription的管理,其中最主要的為call和register的管理,這兩個為sip協(xié)議棧必須實現的部分,另幾個功能為sip協(xié)議棧擴展部分。從這幾個業(yè)務的管理流程出發(fā),

13、在業(yè)務的底層它們會使用到相似的一些功能,如注冊的認證,發(fā)送message,接收message,每個請求和應答形成的transaction,多個transaction組合而成的dialog。在message的處理方面,可以分為兩類,一類為發(fā)送的message,因為是主動發(fā)送,所以上層管理層知道是什么類型的message,lib庫直接提供各類接口供使用。一類為接收到的message,因為不知道是哪種類型,所以需要根據解析出來的message的信息來進行處理,這部分的處理在udp.c文件中。整個lib庫的初始化在exOsip中介紹。Osip包的源代碼框架解析在osip源代碼包中最主要的包括了mess

14、age的相關操作,其中最重要的為message的解析,即從獲取到的一個message中解析生成一個能夠被代碼直接處理的message數據結構osip_message_t。與message結構相關的操作包括根據message數據結構的信息安裝sip協(xié)議規(guī)范組裝成一個message字符串;message結構的初始化和釋放;message結構的拷貝操作;以及從message結構中獲取各種已經解析的成員變量的值和設置各個成員變量的值。在message的解析部分,除了message的頭之外,還包括了body的解析,涉及到sdp協(xié)議,包括對每個sdp字段的解析。在osip源代碼包中,設計了一個與同一個請求

15、相關的所有message的集合transaction,在發(fā)送或接收到一個新的請求的時候就會生成一個transaction,其中ACK和CANCEL請求是比較特殊的,對于非2xx應答的ACK和初始INVITE請求是屬于同一個transaction的,而對于2xx的請求是屬于單獨的transaction的,所以其重傳操作由UAC來控制,而不在INVITE的transaction內部進行控制。CANCEL的請求除了本身建立一個transaction外,根據協(xié)議它還會去匹配要CANCEL掉的請求的transaction,如果匹配成功會CANCEL掉相應的transaction。在osip包中同樣設計了

16、dialog相關操作,包括dialog的建立,dialog信息的保存,dialog的匹配及刪除等操作。其它方面,包括多線程中使用到的鎖和信號量及信號,內部使用到的鏈表,用于事件的隊列(需要先進先出策略),一些平臺無關的封裝,定時器以及常量等的定義。這部分比較簡單,而且都是最底層函數,直接封裝了系統(tǒng)調用層。osip的transaction的event的產生transaction的狀態(tài)變化是由事件來驅動的,當transaction上有事件產生時,根據事件的類型和當前transaction的狀態(tài)來處理該event。Transaction上的事件分為兩類:一為定時器事件,在設定的定時器超時時會產生相應

17、的定時器事件;另一類為事件驅動事件,如發(fā)送一個請求、應答或接收到一個請求、應答,發(fā)送一個ACK和接收到一個ACK,即是由報文產生的事件。定時器事件的產生過程ICT、IST、NICT和NIST的定時器的事件產生流程都一樣,對于每一個transaction,其定時器是有順序的,ICT流程中TIMEOUT_B的優(yōu)先級最高,TIMEOUT_B定時器觸發(fā)后,會觸發(fā)kill transaction的操作。當transactionff隊列中有未處理的事件時,不處理定時器,直接返回,所以在transactionff隊列中總的事件的數量是不多的。所有的定時器函數調用底層同一個定時器檢查函數_osip_trans

18、action_need_timer_x_event。該函數會先檢查該定時器是否啟動,判斷條件為(timer-tv_sec = -1),如果啟動,檢查當前時間是否超過定時器中設定的時間,如果是,則產生新的定時器事件。因為定時器沒有一個單獨的任務,所以是采樣輪訓的方式檢查是否有新的定時器事件產生,而不是根據系統(tǒng)時鐘中斷進行檢測,因此會比較占用系統(tǒng)資源。定時器的啟動和修改使用接口osip_gettimeofday和add_gettimeofday。只需要設定定時器的超時時間,即設定了一個新的定時器。取消一個定時器,只需要修改定時器的timer-tv_sev為-1。報文觸發(fā)的事件包括一個新的invit

19、e、response、ack的發(fā)送或接收,除了對非2xx的應答ack外,其他的請求和應答都會產生一個新的transaction,并且產生一個新的sipevent事件。osip 的transaction的event處理流程在sip協(xié)議棧中為了更快更好的處理transaction,根據協(xié)議棧的描述,劃分為四種不同的transaction,分別為ICT、IST、NICT和NIST。四種不同的transaction會有不同的處理流程和狀態(tài)轉換表,以及使用到不同的定時器。ICT、IST、NICT和NIST的狀態(tài)轉換采樣注冊函數處理方式,為便于管理和使用注冊函數,源碼中使用了四個全局變量管理四種不同類型t

20、ransaction的轉換表:ict_fsm、ist_fsm、nist_fsm和nist_fsm。osip結構如下:struct osipvoid *application_context;/* User defined Pointer */* list of transactions for ict, ist, nict, nist */osip_list_t osip_ict_transactions;/* list of ict transactions */osip_list_t osip_ist_transactions;/* list of ist transactions */o

21、sip_list_t osip_nict_transactions;/* list of nict transactions */osip_list_t osip_nist_transactions;/*300時,client端發(fā)送ACK,當重復接收到該invite的response時,重發(fā)該ACK,確保server端在kill tranction前能接收到ACK。IST的處理流程同ICT的處理流程,處理osip中的osip_ist_transaction鏈表。IST的相關event的注冊處理函數在ist_fsm.c文件和ist.c文件。IST使用了定時器TIMEOUT_G、TIMEOUT_H

22、和TIMEOUT_I。使用方式與ICTL類似,詳細見協(xié)議棧說明。NICT的處理流程同ICT的處理流程,處理osip中的osip_nict_transaction鏈表。NICT的相關event的注冊處理函數在nict_fsm.c文件和nict.c文件。NICT使用了定時器TIMEOUT_E、TIMEOUT_F和TIMEOUT_K。NIST的處理流程同ICT的處理流程,處理osip中的osip_nist_transaction鏈表。NIST的相關event的注冊處理函數在nist_fsm.c文件和nist.c文件。NIST使用了定時器TIMEOUT_J。Osip報文的解析sip協(xié)議報文的解析整理流

23、程當接收到一個message的時候,需要解析該message,生成一個代碼能夠處理的數據結構,該結構定義為struct osip_message,該結構定義的一個message的全部相關信息,這些信息主要是供transaction和dialog及dialog的更上一層如call,notify等的使用。對一個message的解析流程如下圖所示:在接收到一個message時,調用函數osip_message_parse進行message的解析。首先調用函數osip_util_replace_all_lws替換掉message中的連續(xù)出現的 rnt、rt、nt、rn 、r 、n 為空格,messag

24、e是以0為結束標志的,message的headers和body之間的分界是以rnrn為標志的,替換只替換到rnrn為止,即只替換headers部分出現的t、r、n。由于sip協(xié)議棧規(guī)定,每個headers都是起新行,而且新行的頭一個字符不為空格或t,所以兩個header之間的rn不會被替換掉,替換的只是一個允許multi合并項的header的內部多個值之間的“rnt”或“rn ”。舉例如下:有兩個header,其中Subject只允許單個值出現, Route允許有多個值出現,而且允許分行,但是分行必須以空格或t開頭,而Subject和Route行必需頂格開始,前面是沒有空格或t的,osip_u

25、til_replace_all_lws函數將Route header value中的兩行間的rnt轉化為空格,即在邏輯上就成為一行了。Subject: Lunch Route: , 一個message由三部分組成,首先是message的startline部分,該行指明這是一個sip的message,包括sip標志,請求或應答說明,狀態(tài)值,然后以rn做為和headers的分隔符。該rn不會被osip_util_replace_all_lws替換為空格,如請求的INVITE sip:bob SIP/2.0或應答的SIP/2.0 200 OK,在三個屬性之間有且僅有一個空格。起始行的解析由_osip

26、_message_startline_parse進行解析,解析得到message的類型,message的sipversion以及message的status_code,當status_code為初始化值0時,該message為一個請求,否則為應答。請求的startline由_osip_message_startline_parsereq進行解析,得到請求的request_uri;應答的startline由_osip_message_startline_parseresp進行解析。Startline部分的解析是嚴格安裝出現的三個屬性的順序進行解析的,并將解析結果保存在osip_message的結

27、構成員變量中。然后解析messge的headers部分,調用函數 msg_headers_parse。說明見osip的header報文頭解析。如果message中在headers之后不是結束符0,則繼續(xù)解析message的負載部分,調用函數msg_osip_body_parse進行解析。Message的body解析首先查詢headers頭解析中保存的content即body的屬性:content_type,如果content_type中的type不為multipart,即不支持多種mime方式的content,說明body中就一個編碼方式,直接將整個body解析為一個內容;如果type為mul

28、titype,說明有多個編碼方式的body組合在一起形成一個整體的body,則以”-”為分隔符解析body,將body分為多個mime編碼方式的字符串,每個解析后的body內容保存在osip_message結構中的bodies結構成員中。Osip報文頭的解析在解析message的header的時候,因為前面的osip_util_replace_all_lws已經轉化了單個header內部出現的r、n和t為空格,所以每個header之間可以使用rn做為分隔符進行分隔。如果字符串開頭start_of_header已經到達結束符”0”,則全部header解析完畢,返回成功;調用_osip_find_

29、next_crlf找到這個header的結束字符并保存在end_of_header中;如果start_of_header為r或n,則已經解析到rnrn即headers的結束字符串,則返回成功,并且保存start_of_header到body中,即body是從rn字符串開始解析的,所以在body解析時,需要跳過rn及之后的空格部分;根據header內部分隔符“:”,取出header的hname和hvalue,其中hvalue在某些hname的情況下是允許為空的,然后調用osip_message_set_multiple_header來解析該header的hvalue字符串;解析成功后,置star

30、t_of_header為已經解析完的header的end_of_header,開始解析下一個header。在osip_message_set_multiple_header中,將headers分為兩類,一類如上面例子中的Subject,只允許一個值,則直接調用osip_message_set_header進行解析;一類如上面例子中的Router,允許多個值,根據sip協(xié)議,每個值之間以“,”進行分隔,所以需要查詢整個hvalue字符串,根據”,”將hvalue分隔成多個值,每個值調用osip_message_set_header進行解析并保存解析結果到osip_message的數據成員變量中。

31、因為hvalue允許使用引號將值引起來,所以需要特別處理“,”是否出現在引號內部的問題。只有在引號外部的“,”才是header值的分隔符,而內部的“,”只是一個header值的一部分。osip源碼中osip_message_set_header對于message headers的解析采用注冊函數的方式實現,采用這種方式能夠在后繼版本很方便的進行新的header的添加,并且不會影響到整個源代碼的框架流程。Osip_parser_cfg.c文件中定義了header頭解析所使用到的全局管理變量:static _osip_message_config_t pconfigNUMBER_OF_HEADER

32、S;_osip_message_config_t的結構定義如下:typedef struct _osip_message_config_t char *hname; int (*setheader) (osip_message_t *, const char *); int ignored_when_invalid;_osip_message_config_t;hname為sip協(xié)議定義的頭字段的字符串,這些字符串定義在osip_const.h文件中;函數指針setheader為該協(xié)議header的對應的解析函數;ignored_when_invalid為是否忽略該header解析錯誤的標志,

33、該標志值為1時,在解析該協(xié)議header發(fā)送錯誤時,忽略該錯誤,除sip協(xié)議規(guī)定的幾個必要header之外,其他頭應該采用忽略方式。為了更快的根據header的hname,找到對應的setheader解析函數,采用了hash表的查詢方式,根據hname生成一個hash值,并且需要保證沒有兩個不同的hname對應到同一個hash值中,以提高查詢的速度。調用_osip_message_is_known_header (hname)獲取到在數組中的index, 調用_osip_message_call_method (my_index, sip, hvalue)解析協(xié)議header,并且解析的結果保

34、存在結構osip_message_t * dest,中。每一個header都包含幾個通用的操作:header字符串的解析函數,即上段講到的osip_message_set_xxx解析函數;header解析后的結構的獲取函數,osip_message_get_xxx函數;根據header解析后的結構生成字符串的函數:osip_xxx_str;header解析后的結構的copy函數osip_xxx_clone;header解析后的結構的是否函數:osip_xxx_free;以及header解析結構的初始化函數:osip_xxx_init。對每個header的幾個相關操作最終目的是提供協(xié)議的整個he

35、ader的整體操作,包括osip_message_init,osip_message_free,osip_message_clone和osip_message_parse。uri的解析絕大部分的header的解析都是相識的,只有其中有參數的部分的header的解析會比較復雜,最主要的有from、to、contact等,因為除了本身就有參數之外,其值中的request_uri本身也可以包含有參數,而這兩種參數之間是有區(qū)別的。Sip協(xié)議棧規(guī)定header的表示分為 headers name, headers value和headers parameter。其中name和value之間用“:”分隔,

36、value與parameter之間用“;”分隔,parameter之間也使用“;”相分隔。在結構定義中header的value根據具體header包含的信息進行結構變量的定義,而如果包含parameter則直接定義一個gen_params的鏈表,所有的parameter都保存在這個鏈表中。如下面from的定義,包含有from的名稱及一個url,及相關的parameter: struct osip_from char *displayname; /* Display Name */ osip_uri_t *url; /* url */ osip_list_t gen_params; /* oth

37、er From parameters */ ;對應parameter的解析直接調用_osip_generic_param_parseall,該函數解析header的單個hvalue字符串中包含的所有parameter,在函數內部會根據“;”將字符串劃分為幾個parameter,然后解析每個parameter,將解析結果保存在gen_params鏈表中。Parameter的格式為pname=pvalue類型,等號兩邊允許空格。From、to、contact以及via中間都可能出現url。url的解析接口為osip_uri_parse,輸入為url的字符串,解析的結構保存在結構osip_uri_t

38、之中。url包含有三部分內容:url的基本信息,url的header頭部分和url的參數部分。開始部分與header頭部分用“?”進行分隔,header頭之間用”&”進行分隔,header頭部分與參數部分用”;”進行分隔,參數之間也使用“;”進行分隔。Header部分調用函數osip_uri_parse_headers進行解析,結果保存在osip_uri_t結構中的url_headers成員變量中;parameter部分調用函數osip_uri_parse_params進行解析,其結果保存在osip_uri_t的url_params成員變量中。在from、to、contact等包含url的he

39、ader中,如果url中包含parameter,則整個url必需使用“”括起來,以表示一個完整url部分。所以解析from等header時需要檢查是否包含”字符。添加一個新的協(xié)議header字段需要添加多個一個對該字段進行解析的文件,包含一個header常用到的幾個基本通用操作,如果該header有特殊的地方需要處理,需要增加相關的處理函數,文件名一般定義為osip_xxx.c和osip_xxx.h需要在parser_init中注冊新的header的解析函數,需要修改static _osip_message_config_t pconfigNUMBER_OF_HEADERS中的NUMBER_O

40、F_HEADERS宏值。在osip_const.h中添加新的header的宏定義,osip的相關的常量宏定義都定義在該文件在osip_message.c文件額osip_message_init函數中添加對該header相關結構的初始化操作。在osip_message_free函數中同樣添加對該header的相關釋放操作,在osip_message_clone中添加對該header的clone相關操作。在osip_message_to_str.c文件中的_osip_message_to_str函數中添加該header轉化為string的函數注冊。如果該header不允許重復多個出現,即不允許mu

41、ltiple header,則在osip_message_parse.c文件的 osip_message_set_multiple_header函數中添加對該header的處理。在osip_message.h的頭文件中的osip_message結構中添加對該header字段的結構。在osip_headers.h文件中添加新的header的頭文件引用。osip的transaction的管理transaction的操作主要包括transaction的初始化、transaction的free、transaction的匹配、從transaction中獲取信息和設置transaction信息。根據sip

42、協(xié)議描述一個transaction由5個必要部分組成:from、to、topvia、call-id和cseq,這5個部分一起識別某一個transaction,如果缺少任何一部分,該transaction就會設置失敗。所以對每個部分的設置都會有一個設置函數:_osip_transaction_set_topvia用于設置topvia,對于發(fā)送端topvia為自己的via,對于接收端topvia為將message轉發(fā)到自己的最后一個sip-proxy服務器,_osip_transaction_set_from用于設置message的發(fā)送端,_osip_transaction_set_to用于設置m

43、essage的接收端,_osip_transaction_set_call_id用于設置一個dialog的標識值,該值是隨機生成的,算法保證很長一段時間內生成的cal_id是不相同的,_osip_transaction_set_cseq用于設置cseq值,該值在同一個dialog內部是一直保持增長的,即同一個dialog的后面的transaction的cseq會比前面的transaction的值大,按照sip協(xié)議其初始值可以是隨機數,代碼實現中如果是非register請求,從1開始,如果是register請求的dialog,從20開始。Transaction的初始化發(fā)生在接收到一個新的請求或發(fā)

44、送一個請求的時候,該請求以及經過解析成為一個可以直接使用請求信息的結構osip_message_t。其初始化具體過程如上面所述,在設置完那5個部分后,還需要初始化event的隊列,以及根據osip_message_t的type初始化使用到的定時器結構,如ICT的ict_context。其它部分的初始化在exosip源代碼中實現,相關的如your_instance、in_socket、out_socket和record都是未了方便exosip中對transaction的管理而設置的。Transaction中的event的相關操作在如前面所述。在transaction的匹配中,根據RFC3261的

45、最新sip協(xié)議的描述,由topvia的branch_id是否相同來匹配,如果相同,就是同一個transaction的請求和應答及ACK,為兼容舊版本的transaction的匹配規(guī)則,同時支持根據call_id, cseq, from_tag, to_tag來匹配transaction。如下圖,為便于管理的transaction,所有的transaction保持在osip_t結構的四條鏈表中,按照處理流程的不同分為發(fā)送出去的INVITE類型請求和應答、其它類型請求和應答,接收到的INVITE請求和應答、其它請求和應答。struct osip void *application_context;

46、 /* User defined Pointer */ /* list of transactions for ict, ist, nict, nist */ osip_list_t osip_ict_transactions; /* list of ict transactions */ osip_list_t osip_ist_transactions; /* list of ist transactions */ osip_list_t osip_nict_transactions; /* list of nict transactions */ osip_list_t osip_nis

47、t_transactions; /* list of nist transactions */#if defined(HAVE_DICT_DICT_H) dict *osip_ict_hastable; /* htable of ict transactions */ dict *osip_ist_hastable; /* htable of ist transactions */ dict *osip_nict_hastable; /* htable of nict transactions */ dict *osip_nist_hastable; /* htable of nist tra

48、nsactions */#endif ;在transaction的匹配過程中,如果是發(fā)出的請求,因為本地的transaction都會分配一個不重復的transaction_id,所以只需要比配transaction_id即可;對于incoming的message,如果是request,則匹配branch_id或者為兼容前面版本進行transaction的比配,按照協(xié)議RFC3261的17-2-3節(jié)的方式進行匹配;如果incoming的message是response,則匹配branch_id或根據RFC3261的17-1-3節(jié)的規(guī)則進行匹配。osip中dialog的管理dialog的相關的管理

49、操作包括dialog的初始化建立過程,dialog的銷毀free過程,以及dialog的匹配。此外dialog中保存了相關的路由信息和cseq信息。Dialog結構如下,由call_id、local_tag和remote_tag唯一確定一個dialog: struct osip_dialog char *call_id; /* Call-ID*/ char *local_tag; /* local tag */ char *remote_tag; /* remote tag */ osip_list_t route_set; /* route set */ int local_cseq; /*

50、 last local cseq */ int remote_cseq; /* last remote cseq*/ osip_to_t *remote_uri; /* remote_uri */ osip_from_t *local_uri; /* local_uri */ osip_contact_t *remote_contact_uri; /* remote contact_uri */ int secure; /* use secure transport layer */ osip_dialog_type_t type; /* type of dialog (CALLEE or C

51、ALLER) */ state_t state; /* DIALOG_EARLY | DIALOG_CONFIRMED | DIALOG_CLOSED */ void *your_instance; /* for application data reference */ ;在dialog的初始化時,需要根據是client端或server端來確定dialog結構中的call_id、local_tag和remote_tag的值。根據是client端或server端來確定dialog的type,并且設置dialog的狀態(tài)。當做為client端,并且是在接收到發(fā)出的request的response時

52、,調用osip_dialog_init_as_uac進行初始化dialog;如果是接收到server端發(fā)送過來的request,則調用osip_dialog_init_as_uac_with_remote_request進行dialog的初始化。如果是server端,調用osip_dialog_init_as_uas進行初始化dialog。在dialog的匹配時,當是client端時,調用osip_dialog_match_as_uac進行匹配。檢查接收到的response和dialog中的call_id,to_tag和from_tag是否匹配,如果全部匹配,則匹配到了該dialog。為兼容前

53、面的版本,在dialog的to或者接收到的message的to header沒有tag的情況下,比較dialog和message的from_uri, to_uri。如果匹配,則同樣匹配的dialog。當是server端時,調用osip_dialog_match_as_uas進行匹配。其匹配方法與client端的匹配方法相同。對from_tag和to_tag的匹配處理,在transaction的匹配過程中同樣使用到。Exosip包的源代碼框架解析在exosip源代碼包中包含了提供給上層管理軟件調用的關于call、message、option、refer、register、subscription

54、、publish和insubscription的API,這些API的實現都在ex開頭的c文件中。為這些接口進行服務的函數,包括和osip lib庫進行通信的部分的實現在以j開頭的源文件中如jcall.c,其中jrequest.c和jresponse.c實現了request和response的message的通用構造實現。同時exosip實現了傳輸層的四種不同的傳輸方式供上層的sip協(xié)議棧進行選擇,分別為extl_dtls.c、extl_tcp.c、extl_tls.c和extl_udp.c,它們以注冊的方式在Lib庫啟動的時候注冊到lib庫的鉤子中。為了支持多線程間的通信,在兩個線程間采用pi

55、pe的方式進行實現,如果沒有使用多線程,這部分源代碼在編譯時會被屏蔽掉。對接收到的message進行的邏輯處理在文件udp.c中,這部分是整個協(xié)議棧邏輯比較復雜的地方。需要根據sip協(xié)議棧的標識描述和代碼實現框架進行整理的把握。Lib庫的初始化和銷毀整個sip 的lib庫有一個總的管理結構struct exosip_t eXosip,該全局變量在lib庫被使用之前需要初始化,初始化函數為exconf.c文件的eXosip_init函數。Exosip_t結構如下: struct eXosip_tt struct eXtl_protocol *eXtl; char transport10; cha

56、r *user_agent; eXosip_call_t *j_calls; /* my calls */#ifndef MINISIZE eXosip_subscribe_t *j_subscribes; /* my friends */ eXosip_notify_t *j_notifies; /* my susbscribers */#endif osip_list_t j_transactions; eXosip_reg_t *j_reg; /* my registrations */#ifndef MINISIZE eXosip_pub_t *j_pub; /* my publica

57、tions */#endif#ifdef OSIP_MT void *j_cond; void *j_mutexlock;#endif osip_t *j_osip; int j_stop_ua;#ifdef OSIP_MT void *j_thread; jpipe_t *j_socketctl; jpipe_t *j_socketctl_event;#endif osip_fifo_t *j_events; jauthinfo_t *authinfos; int keep_alive; int learn_port;#ifndef MINISIZE int http_port; char

58、http_proxy256; char http_outbound_proxy256; int dontsend_101;#endif int use_rport; char ipv4_for_gateway256; char ipv6_for_gateway256;#ifndef MINISIZE char event_package256;#endif struct eXosip_dns_cache dns_entriesMAX_EXOSIP_DNS_ENTRY; struct eXosip_account_info account_entriesMAX_EXOSIP_ACCOUNT_IN

59、FO; struct eXosip_http_auth http_authsMAX_EXOSIP_HTTP_AUTH; CbSipCallback cbsipCallback; p_access_network_info *p_a_n_i; digest_cave_response *cav_v; ;在該結構中,最重要的幾個成員變量如下:int j_stop_ua; 協(xié)議棧啟動和停止的控制參數,當j_stop_ua為0時,lib庫啟動,為非0時,lib庫停止。eXosip_call_t *j_calls; j_calls用于管理全部的通話,所有的call在這個結構中形成一個鏈表結構。Call結

60、構如下: struct eXosip_call_t int c_id; eXosip_dialog_t *c_dialogs; osip_transaction_t *c_inc_tr; osip_transaction_t *c_out_tr; int c_retry; /* avoid too many unsuccessfull retry */ void *external_reference; eXosip_call_t *next; eXosip_call_t *parent; ;其中的c_id為分配的call_id,c_dialogs為同一個call中的dialog的集合。c_i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論