linphone 分析4 接电话分析

case EXOSIP_CALL_INVITE:表示收到了一个呼叫的消息。执行:inc_new_call(Sal *sal, eXosip_event_t *ev)

 

 

static void inc_new_call(Sal *sal, eXosip_event_t *ev){

SalOp *op=sal_op_new(sal);

osip_from_t *from,*to;

osip_call_info_t *call_info;

char *tmp=NULL;

sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);s得到sdp信息

osip_call_id_t *callid=osip_message_get_call_id(ev->request);

osip_call_id_to_str(callid,&tmp);

op->base.call_id=ms_strdup(tmp);

osip_free(tmp);

 

取一些参数如:origin
uareplacesfrom ,to ,sdpcall_info,tid,cid, did,等等

 

set_network_origin(op,ev->request);

set_remote_contact(op,ev->request);

set_remote_ua(op,ev->request);

set_replaces(op,ev->request);

sal_op_set_custom_header(op,sal_exosip_get_custom_headers(ev->request));

if (sdp){

op->sdp_offering=FALSE;

op->base.remote_media=sal_media_description_new();

sdp_to_media_description(sdp,op->base.remote_media);

sdp_message_free(sdp);

}else op->sdp_offering=TRUE;

 

from=osip_message_get_from(ev->request);

to=osip_message_get_to(ev->request);

osip_from_to_str(from,&tmp);

sal_op_set_from(op,tmp);

osip_free(tmp);

osip_from_to_str(to,&tmp);

sal_op_set_to(op,tmp);

osip_free(tmp);

 

osip_message_get_call_info(ev->request,0,&call_info);

if(call_info)

{

osip_call_info_to_str(call_info,&tmp);

if( strstr(tmp,"answer-after=") != NULL)

{

op->auto_answer_asked=TRUE;

ms_message("The caller asked to automatically answer the call(Emergency?)\n");

}

osip_free(tmp);

}

 

op->tid=ev->tid;

op->cid=ev->cid;

op->did=ev->did;

sal_add_call(op->base.root,op);

sal->callbacks.call_received(op);

}

 

 

 

 

 

 

static void call_received(SalOp *h)

 

{

LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));

LinphoneCall *call;

const char *from,*to;

LinphoneAddress *from_addr, *to_addr;

bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE);

/* first check if we can answer successfully to this invite */

if (lc->presence_mode==LinphoneStatusBusy ||

    lc->presence_mode==LinphoneStatusOffline ||

    lc->presence_mode==LinphoneStatusDoNotDisturb ||

    lc->presence_mode==LinphoneStatusMoved){

if (lc->presence_mode==LinphoneStatusBusy )

sal_call_decline(h,SalReasonBusy,NULL);

else if (lc->presence_mode==LinphoneStatusOffline)

sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL);

else if (lc->presence_mode==LinphoneStatusDoNotDisturb)

sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL);

else if (lc->alt_contact!=NULL && lc->presence_mode==LinphoneStatusMoved)

sal_call_decline(h,SalReasonRedirect,lc->alt_contact);

sal_op_release(h);

return;

}

判断收处于呼叫状态,是否达到最大呼叫数目

if (!linphone_core_can_we_add_call(lc)){/*busy*/

sal_call_decline(h,SalReasonBusy,NULL);

sal_op_release(h);

return;

}

from=sal_op_get_from(h);

to=sal_op_get_to(h);

from_addr=linphone_address_new(from);

to_addr=linphone_address_new(to);

 

if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_a_call_pending(lc)){

ms_warning("Receiving another call while one is ringing or initiated, refusing this one with busy message.");

sal_call_decline(h,SalReasonBusy,NULL);

sal_op_release(h);

linphone_address_destroy(from_addr);

linphone_address_destroy(to_addr);

return;

}

call=linphone_call_new_incoming(lc,from_addr,to_addr,h);

/* the call is acceptable so we can now add it to our list */

linphone_core_add_call(lc,call);

linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */

 

if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) {

/* Defer ringing until the end of the ICE candidates gathering process. */

ms_message("Defer ringing to gather ICE candidates");

return;

}

#ifdef BUILD_UPNP

if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseUpnp) && (call->upnp_session != NULL)) {

/* Defer ringing until the end of the ICE candidates gathering process. */

ms_message("Defer ringing to gather uPnP candidates");

return;

}

#endif //BUILD_UPNP

 

linphone_core_notify_incoming_call(lc,call);

}

 

 

 

 

LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){

LinphoneCall *call=ms_new0(LinphoneCall,1);

char *from_str;

const SalMediaDescription *md;

 

call->dir=LinphoneCallIncoming;

sal_op_set_user_pointer(op,call);

call->op=op;

call->core=lc;

判决是否发ping指令

if (lc->sip_conf.ping_with_options){

#ifdef BUILD_UPNP

if (lc->upnp != NULL && linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp &&

linphone_upnp_context_get_state(lc->upnp) == LinphoneUpnpStateOk) {

#else //BUILD_UPNP

{

#endif //BUILD_UPNP

/*the following sends an option request back to the caller so that

 we get a chance to discover our nat'd address before answering.*/

call->ping_op=sal_op_new(lc->sal);

from_str=linphone_address_as_string_uri_only(from);

sal_op_set_route(call->ping_op,sal_op_get_network_origin(op));

sal_op_set_user_pointer(call->ping_op,call);

sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from,NULL),from_str);

ms_free(from_str);

}

}

 

linphone_address_clean(from);

linphone_core_get_local_ip(lc,NULL,call->localip);

linphone_call_init_common(call, from, to);      init一个call

call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/

linphone_core_init_default_params(lc, &call->params);

md=sal_call_get_remote_media_description(op);       拿到发送过来的SDP

call->params.has_video &= !!lc->video_policy.automatically_accept;

if (md) {

// It is licit to receive an INVITE without SDP

// In this case WE chose the media parameters according to policy.

call->params.has_video &= linphone_core_media_description_contains_video_stream(md);

}

switch (linphone_core_get_firewall_policy(call->core)) {

case LinphonePolicyUseIce:

call->ice_session = ice_session_new();

ice_session_set_role(call->ice_session, IR_Controlled);

linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));

if (call->ice_session != NULL) {

linphone_call_init_media_streams(call);

linphone_call_start_media_streams_for_ice_gathering(call);

if (linphone_core_gather_ice_candidates(call->core,call)<0) {

/* Ice candidates gathering failed, proceed with the call anyway. */

linphone_call_delete_ice_session(call);

linphone_call_stop_media_streams_for_ice_gathering(call);

}

}

break;

case LinphonePolicyUseStun:

call->ping_time=linphone_core_run_stun_tests(call->core,call);

/* No break to also destroy ice session in this case. */

break;

case LinphonePolicyUseUpnp:

#ifdef BUILD_UPNP

if(!lc->rtp_conf.disable_upnp) {

call->upnp_session = linphone_upnp_session_new(call);

if (call->upnp_session != NULL) {

linphone_call_init_media_streams(call);

if (linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op))<0) {

/* uPnP port mappings failed, proceed with the call anyway. */

linphone_call_delete_upnp_session(call);

}

}

}

#endif //BUILD_UPNP

break;

default:

break;

}

call->camera_active=call->params.has_video;

discover_mtu(lc,linphone_address_get_domain(from));

return call;

 

}

 

 

 

 

 

 

 

 

 

 

 

void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call)

 

{

char *barmesg;

char *tmp;

LinphoneAddress *from_parsed;

SalMediaDescription *md;

bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);

const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);

 

linphone_call_make_local_media_description(lc,call);

sal_call_set_local_media_description(call->op,call->localdesc);

md=sal_call_get_final_media_description(call->op);开始进行sdp,媒体类型协商

if (md){

if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){

sal_call_decline(call->op,SalReasonMedia,NULL);

linphone_call_unref(call);

return;

}

}

 

from_parsed=linphone_address_new(sal_op_get_from(call->op));

linphone_address_clean(from_parsed);

tmp=linphone_address_as_string(from_parsed);

linphone_address_destroy(from_parsed);

barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"),

    (sal_call_autoanswer_asked(call->op)) ?_(" and asked autoanswer."):_("."));

if (lc->vtable.show) lc->vtable.show(lc);

if (lc->vtable.display_status)

    lc->vtable.display_status(lc,barmesg);提示电话来了的消息//XX is contacting you?

 

/* play the ring if this is the only call*/

if (ms_list_size(lc->calls)==1){

lc->current_call=call;

if (lc->ringstream && lc->dmfs_playing_start_time!=0){

ring_stop(lc->ringstream);

lc->ringstream=NULL;

lc->dmfs_playing_start_time=0;

}

if (lc->sound_conf.ring_sndcard!=NULL){

if(lc->ringstream==NULL && lc->sound_conf.local_ring){

MSSndCard *ringcard=lc->sound_conf.lsd_card ?lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard;

ms_message("Starting local ring...");

与此同时,开始ring_start(),播放ringback(

lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,ringcard);

}

else

{

ms_message("the local ring is already started");

}

}

}else{

/* else play a tone within the context of the current call */

call->ringing_beep=TRUE;

linphone_core_play_named_tone(lc,LinphoneToneCallWaiting);

}

 

linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");

 

if (call->state==LinphoneCallIncomingReceived){

       同时发180消息

sal_call_notify_ringing(call->op,propose_early_media || ringback_tone!=NULL);

 

if (propose_early_media || ringback_tone!=NULL){

linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");

md=sal_call_get_final_media_description(call->op);

linphone_core_update_streams(lc,call,md);

}

if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){

linphone_core_accept_call(lc,call);

}

}

linphone_call_unref(call);

 

ms_free(barmesg);

ms_free(tmp);

}

 

 

 

 

 

Answer 这个call   linphone_core_accept_call

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值