【正文】
ESPONSEFOR(resp,requestname) \ (0==strcmp(respcseqmethod,requestname))對于其他相關操作的API,請務必參閱osip/。此庫的語法分析需要在運行之前做以下初始化工作,下面的的函數(shù)必須被使用,且只能運作一次!int parser_init()。對于定義結構的處理,你是可以調用所謂的標準函數(shù)。例如sip_t和from_t結構,你可以使用xxx_init函數(shù)對結構進行初始化(這其中包括初賦值和內存分配等等)。你必須調用相對于初始化函數(shù)的釋放結構函數(shù)xxx_free進行釋放操作,以防止內存漏洞。sip_t *msg。msg_init(amp。msg)。msg_free(msg)。sfree(msg)。url_t *url。url_init(amp。url)url_free(url)。sfree(url)。如何創(chuàng)建一個url和requesturi,下面的流程就是答案。這里有一個樣例,我們就對利用此值進行設定。INVITE sip:chenshx@ SIP/url_t *url。url_init(amp。url)。url_setscheme(url,”sip”)。url_setusername(url,”chenshx”)。url_sethost(url,””)。msg_setmethod(msg,”INVITE”)。msg_seturi(msg,url)。msg_setversion(msg,””)。如何在消息體中增加字段?我提供給您兩條思路,一個看下面的樣例,另一個是看rfc2543。下面的頭部是強制的,請牢記于心。ViaCseqCallIdToFromContactContentlengthContenType之后就是body{url_t *url。to_t *to。url_init(amp。url)。url_setusername(url,sstrdup(jack))。url_sethost(url,sstrdup())。to_init(amp。to)。to_seturl(to,url)。to_setdisplayname(to,sstrdup(jack...))。msg_setto(msg, to)。 }/* the same API is available for the from_t structure */ {from_t *from。/* allocate a url_t */url_init(amp。url)。url_setusername(url,sstrdup(cha))。url_sethost(url,sstrdup())。/* allocate a from_t */from_init(amp。from)。from_seturl(from,url)。from_setdisplayname(from,sstrdup(My love))。from_set_tag(from,sstrdup(a48a))。msg_setfrom(msg, from)。 } {via_t *via。via_init(amp。via)。via_setversion(via,sstrdup())。via_setprotocol(via,sstrdup(UDP))。via_sethost(via,sstrdup())。via_set_branch(via,sstrdup(branch),sstrdup())。msg_setvia(msg, via)。 } {cseq_t *cseq。cseq_init(amp。cseq)。...msg_setcseq(msg, cseq)。 } {callid_t *callid。callid_init(amp。callid)。callid_setnumber(callid,sstrdup(f81d4))。callid_sethost(callid,sstrdup())。msg_setcallid(msg, callid)。 } /* this API can also be used, but it is much more time consuming! */ msg_setcontact(msg,sip:jacK@)。 /* Let39。s add some headers */ msg_setheader(msg,sstrdup(SuBjecT),sstrdup(Need support for oSIP!))。 /* add a body */msg_setbody(msg,v=0\r\no=user1 53655765 2353687637 IN IP4 \r\ns=Mbone Audio\r\ni=Discussion of Mbone Engineering Issues\r\ne=mbone@\r\nc=IN IP4 \r\nt=0 0\r\nm=audio 3456 RTP/AVP 0\r\na=rtpmap:0 PCMU/8000\r\n)。結構信息轉化成字符串將一個定義的結構轉化為串,這在處理完信息之后要發(fā)送這個動作時必須調用的。之后就是釋放掉結構初始化所占用的資源。sip_t *msg。char *dest。msg_init(amp。msg)。對msg的操作。if(msg_2char(msg,amp。dest)!=0){printf(“\nmsg_2char調用失敗。\n”)。continue。}msg_free(msg)。sfree(msg)。sfree(dest)。提醒:語法分析器過于容忍一些我們的一些失誤,例如可能在display name中加入了逗號,雖然這是不允許的,但分析器卻“容忍”了。這就使你必須時刻警惕可能發(fā)生的一切,擦亮你的眼睛,關注每一問題。如何提高語法分析器的性能 提高棧的性能,你可以通過配置語法分析在連接時選取一些頭部必須完全解碼。(在運行時進行少量工作也是被允許的)在執(zhí)行代理服務器時,你可以發(fā)現(xiàn)這對于性能提高很有用。第五章 有限狀態(tài)機有限狀態(tài)機用以表示SIP會話過程,用數(shù)學方法表示狀態(tài)的轉換。每一時刻協(xié)議機(發(fā)送方或接受方)總處于一個特定的狀態(tài),其狀態(tài)是由所有變量值組成的,包括計數(shù)器在內。./。./libosip是開發(fā)庫目錄。includeosip/是描述SIP有限狀態(tài)機的API的庫文件。事務處理和事件(Events)事務處理的定義和目的 在RFC2543中,事務處理被用于定義SIP事務處理的上下文關系。利用transaction_t結構定義事務處理信息,所以我們不需要明白每一個屬性。事務處理模型如下:Ining msgTimeout evtMsg to sendUser moduleTimer moduleTransport moduleTRANSAC.2TRANSAC.1事務處理的上下文your_instance屬性沒有被開發(fā)庫用到,我們可以用它指向個人設定的上下文。我們以transactionid作為事務處理鏈表中每個個體的唯一標識。transactionff是一個FIFO(First In First Out先進先出)結構,用以標識此事務處理的事件(sipevent_t)。這個proxy屬性指出被用于傳輸?shù)闹鳈C和端口,所有的請求被強制傳輸?shù)酱藀roxy,而不論requesturi包含的是什么。typedef struct _transaction_t{void *your_instance。 /*add whatever you want here. */int transactionid。 /*simple id used to identify the tr.*/fifo_t *transactionff。 /*events must be added in this fifo*/from_t *from。 /* CALLLEG definition */to_t *to。call_id_t *callid。cseq_t *cseq。sip_t *lastrequest。 /*last request received or sent */sip_t *lastresponse。 /*last response received or sent */state_t state。 /*state of transaction*/statemachine_t *statemachine。 /* statemachine of transaction*/time_t birth_time。 /*birth_date of transaction*/time_t pleted_time。 /*end date of transaction*/int retransmissioncounter。 /*facilities for internal timer*/url_t *proxy。 /*url used to send requests*/ void *config。 /*transaction is managed by config*/} transaction_t。事件的定義和目的sipevent目標被用于控制SIP事務處理中的元素。在有限狀態(tài)機中有3種事件(Events):接收SIP消息(請求和應答)發(fā)送SIP消息(請求和應答)計時器事件(重傳和上下文刪除或者說結束)type總是指向事件的類型。transactionid作為內部使用。當事件是因為SIP消息引起的,則sip就是sip_t結構消息。typedef struct _sipevent_t{type_t type。int transactionid。sip_t *sip。}sipevent_t。事務處理的APIosip_init[功能描述]為osip_t結構初始化并分配內存。[參數(shù)描述]int osip_init(oisp_t **osip)。成功返回0osip_free[功能描述]釋放osip結構。[參數(shù)描述]void osip_free(osip_t *osip)。osip_init_proxy[功能描述]設定與osip結構相關事務處理的默認代理。[參數(shù)描述]void osip_init_proxy(osip_t *osip,url_t *url)。osip_execute[功能描述](僅限于非多線程的應用程序設計)執(zhí)行在osip結構當中事務處理的事件(Events)。[參數(shù)描述]int osip_execute(osip_t *osip)。成功返回0osip_distribute_event[功能描述]分發(fā)一個SIP事件(對于接收消息事件ining message evt)到osip結構當中的FIFO[參數(shù)描述]transaction_t *osip_distribute_event(osip_t *osip,sipevent_t *se)。osip_parse[功能描述]對字符串buf進行語法分析,并生成SIP到來消息事件。[參數(shù)描述]sipevent_t *osip_parse(char *buf)。osip_new_event[功能描述](被計時器使用)用于創(chuàng)建一個新的SIP事件(event),并帶有類型屬性type和transactionid。[參數(shù)描述]sipevent_t *osip_new_event(type_t type,int transactionid)。osip_new_ining_event[功能描述]為接收SIP消息創(chuàng)建新的SIP事件。[參數(shù)描述]sipevent_t *osip_new_ining_event(sip_t *sip)。sip_new_outgoing_event[功能描述]為發(fā)送SIP消息創(chuàng)建新的SIP事件。[參數(shù)描述]sipevent_t *osip_new_outgoing_event(sip_t *sip)。osip_find_asiningmessage[功能描述]發(fā)現(xiàn)(或創(chuàng)建)與接收SIP消息相關事務處理。[參數(shù)描述]transaction_t *osip_find_adiningmessage(osip_t *osip,sipevent_t *sipevent)。osip_find_asoutgoingmessage[功能描述]發(fā)現(xiàn)與發(fā)送SIP消息相關的事務處理。[參數(shù)描述]transaction_t *osip_find_asoutgoingmessage(osip_t *osip,sipevent_t *sipevent)。osip_find_byid[功能描述]尋找?guī)в邢嗤瑃ransactionid屬性值的事務處理。[參數(shù)描述]transation_t *osip_find_byid(osip_t *osip,int transactionid)。osip_remove_byid[功能描述]刪除帶有相同transa