@1、exosip初始化
qutecom/wifo/phapi/phapi.c
fun:owplInit()
Line:291
eXosip_set_user_agent(ua);设置SIP包头域User-Agent="qutecom/rev-335d495adbc1-trunk",即SIP客户端名称。
return_code = eXosip_init(0,0,udpPort,tcpPort,tlsPort);
if (return_code != 0){
owplLogError("eXosip_init failed");
return OWPL_RESULT_FAILURE;
}
//...
{
const char * ua=QUTECOM_UA;
eXosip_set_user_agent(ua);
}
@2、创建一个INVITE请求包
拨出电话需要构建一个INVITE发给服务器,服务器转发给另一个UAC。
调用关系:
PhApiWrapper::makeCall()
==>owplCallConnect()
==>phLinePlaceCall_withCa()
==>eXosip_build_initial_invite()
函数声明:
qutecom/wifo/eXosip/include/eXosip/eXosip.h
/**
* Build a default INVITE message for a new call.
*
* @param invite Pointer for the SIP element to hold.
* @param to SIP url for callee. * @param from SIP url for caller.
* @param route Route header for INVITE. (optionnal)
* @param subject Subject for the call.
*/
int eXosip_build_initial_invite(osip_message_t **invite, char *to, char *from, char *route, char *subject);
作用:
构建一个INVITE消息。
实现:
File: qutecom/wifo/eXosip/src/jrequest.c
/* this method can't be called unless the previous INVITE transaction is over. */
int eXosip_build_initial_invite(osip_message_t **invite, char *to, char *from,char *route, char *subject){
int i; if (to!=NULL && *to=='/0')
return -1; osip_clrspace(to);
//清除空格 osip_clrspace(subject);
osip_clrspace(from);
osip_clrspace(route);
if (route!=NULL && *route=='/0')
route=NULL;
if (subject!=NULL && *subject=='/0')
subject=NULL;
//构建INVITE包
i = generating_request_out_of_dialog(invite, "INVITE", to, from, route);
if (i!=0) return -1;
#if 0 if (subject==NULL)
osip_message_set_subject(*invite, "New Call");
else osip_message_set_subject(*invite, subject);
#else if (subject!=NULL)
osip_message_set_subject(*invite, subject);
//设置SIP头域的SUBJECT字段 //"Subject: Phone call"
#endif /* after this delay, we should send a CANCEL */
//设置超时
owsip_message_set_expires(*invite, "120");
/* osip_message_set_organization(*invite, "Jack's Org"); */
return 0;}
函数generating_request_out_of_dialog调用generating_request_out_of_dialog2
generating_request_out_of_dialog2在qutecom/wifo/eXosip/src/jrequest.c实现
部分代码
static intgenerating_request_out_of_dialog2(osip_message_t **dest, char *method_name, char *to, char *from, char *proxy, int seqnum){
//...
i = osip_message_init(&request);
//初始化 if (i!=0) return -1;
/* prepare the request-line */
osip_message_set_method(request, osip_strdup(method_name));
osip_message_set_version(request, osip_strdup("SIP/2.0"));//"INVITE sip:to@192.168.105.14 SIP/2.0"
osip_message_set_status_code(request, 0);
osip_message_set_reason_phrase(request, NULL);//
//...
i = osip_message_set_to(request, to);//"To: <sip:to@192.168.105.14>"
//...
osip_message_set_from(request, from);//
osip_from_set_tag(request->from, osip_from_tag_new_random());//"rom: <sip:from@192.168.105.5>;tag=29244"
//...
osip_call_id_set_number(callid, cidrand);//"Call-ID: 8103"
//... osip_cseq_set_number(cseq, num);
osip_cseq_set_method(cseq, osip_strdup(method_name));
request->cseq = cseq; //"CSeq: 20 INVITE"
//...
osip_message_set_max_forwards(request, "70");
/* a UA should start a request with 70 */
//Max-Forwards: 70
//...
osip_message_set_via(request, tmp);//"Via: SIP/2.0/UDP 192.168.105.5:5060;rport;branch=z9hG4bK2195"
//...
osip_message_set_contact (request, contact) ;//"Contact: <sip:from@192.168.105.5:5060>"
//...
osip_message_set_user_agent(request, eXosip.user_agent);//"User-Agent: QuteCom2.2.1 (eXosip2/3.3.0)"
//...
//设定完头域后,INVITE消息应该长得像这样:
//INVITE sip:to@192.168.105.14 SIP/2.0
//Via: SIP/2.0/UDP 192.168.105.5:5060;rport;branch=z9hG4bK2195
//From: <sip:from@192.168.105.5>;tag=29244
//To: <sip:to@192.168.105.14>
//Call-ID: 8103
//CSeq: 20 INVITE
//Contact: <sip:from@192.168.105.5:5060>
//Max-Forwards: 70
//User-Agent: Linphone/3.2.1 (eXosip2/3.3.0)
//Subject: Phone call //subject在eXosip_build_initial_invite中被设置。在本函数调用后随即调用
}
这个函数调用了oSip2库的一系列xxsetxx函数设置INVITE包的各个头域。
头域的定义在《sip中文参考手册》P122 20 头域一节有完整说明
《sip中文参考手册》已经放在资源中。