static void call_received(SalOp *h){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
- char *barmesg;
LinphoneCall *call;
const char *from,*to;
- char *tmp;
- LinphoneAddress *from_parsed;
LinphoneAddress *from_addr, *to_addr;
- SalMediaDescription *md;
- bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE);
- const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
/* first check if we can answer successfully to this invite */
if (lc->presence_mode==LinphoneStatusBusy ||
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
sal_call_set_local_media_description(h,call->localdesc);
- md=sal_call_get_final_media_description(h);
-
- if (md && sal_media_description_empty(md)){
- sal_call_decline(h,SalReasonMedia,NULL);
- linphone_call_unref(call);
- return;
- }
/* the call is acceptable so we can now add it to our list */
linphone_core_add_call(lc,call);
-
- from_parsed=linphone_address_new(sal_op_get_from(h));
- 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(h)) ?_(" and asked autoanswer."):_("."));
- if (lc->vtable.show) lc->vtable.show(lc);
- if (lc->vtable.display_status)
- lc->vtable.display_status(lc,barmesg);
-
- /* 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...");
- 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_tone(lc);
- }
-
-
linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */
- linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
-
- if (call->state==LinphoneCallIncomingReceived){
- sal_call_notify_ringing(h,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(h);
- 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);
- }
+ if (linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) {
+ /* Defer ringing until the end of the ICE candidates gathering process. */
+ ms_message("Defer ringing to gather ICE candidates");
+ return;
}
- linphone_call_unref(call);
- ms_free(barmesg);
- ms_free(tmp);
+ linphone_core_notify_incoming_call(lc,call);
}
static void call_ringing(SalOp *h){
call->camera_active=call->params.has_video;
switch (linphone_core_get_firewall_policy(call->core)) {
case LinphonePolicyUseIce:
- linphone_core_gather_ice_candidates(call->core, call);
+ 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. */
+ ice_session_destroy(sal_op_get_ice_session(call->op));
+ sal_op_set_ice_session(call->op, NULL);
+ linphone_call_stop_media_streams(call);
+ }
break;
case LinphonePolicyUseStun:
linphone_core_run_stun_tests(call->core,call);
rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq);
ortp_ev_queue_flush(call->audiostream_app_evq);
ortp_ev_queue_destroy(call->audiostream_app_evq);
+ call->audiostream_app_evq=NULL;
if (call->audiostream->ec){
const char *state_str=NULL;
}
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL) {
+ OrtpEvent *ev;
+
// Beware that the application queue should not depend on treatments fron the
// mediastreamer queue.
video_stream_iterate(call->videostream);
- if (call->videostream_app_evq){
- OrtpEvent *ev;
- while (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq))){
- OrtpEventType evt=ortp_event_get_type(ev);
- OrtpEventData *evd=ortp_event_get_data(ev);
- if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
- linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
- } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
- call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->session);
- if(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp != NULL)
- freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp);
- call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp = evd->packet;
- evd->packet = NULL;
- if (lc->vtable.call_stats_updated)
- lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
- } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
- memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->session), sizeof(jitter_stats_t));
- if(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp != NULL)
- freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp);
- call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp = evd->packet;
- evd->packet = NULL;
- if (lc->vtable.call_stats_updated)
- lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
- } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
- if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) {
- linphone_core_update_call(lc, call, &call->current_params);
- }
- } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
- if (call->state==LinphoneCallOutgoingInit) {
- linphone_call_stop_media_streams(call);
- if (evd->info.ice_processing_successful==FALSE) {
- ice_session_destroy(sal_op_get_ice_session(call->op));
- sal_op_set_ice_session(call->op, NULL);
- }
- linphone_core_start_invite(call->core,call,NULL);
- }
+ while (call->videostream_app_evq && (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq)))){
+ OrtpEventType evt=ortp_event_get_type(ev);
+ OrtpEventData *evd=ortp_event_get_data(ev);
+ if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
+ linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
+ } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
+ call->stats[LINPHONE_CALL_STATS_VIDEO].round_trip_delay = rtp_session_get_round_trip_propagation(call->videostream->session);
+ if(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp != NULL)
+ freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp);
+ call->stats[LINPHONE_CALL_STATS_VIDEO].received_rtcp = evd->packet;
+ evd->packet = NULL;
+ if (lc->vtable.call_stats_updated)
+ lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
+ } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
+ memcpy(&call->stats[LINPHONE_CALL_STATS_VIDEO].jitter_stats, rtp_session_get_jitter_stats(call->videostream->session), sizeof(jitter_stats_t));
+ if(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp != NULL)
+ freemsg(call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp);
+ call->stats[LINPHONE_CALL_STATS_VIDEO].sent_rtcp = evd->packet;
+ evd->packet = NULL;
+ if (lc->vtable.call_stats_updated)
+ lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
+ } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
+ if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) {
+ linphone_core_update_call(lc, call, &call->current_params);
+ }
+ } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
+ IceSession *ice_session = sal_op_get_ice_session(call->op);
+ linphone_call_stop_media_streams(call);
+ if (evd->info.ice_processing_successful==TRUE) {
+ ice_session_compute_candidates_foundations(ice_session);
+ ice_session_eliminate_redundant_candidates(ice_session);
+ ice_session_choose_default_candidates(ice_session);
+ } else {
+ ice_session_destroy(ice_session);
+ sal_op_set_ice_session(call->op, NULL);
+ }
+ if (call->state==LinphoneCallOutgoingInit) {
+ linphone_core_start_invite(call->core,call,NULL);
+ } else {
+ linphone_core_notify_incoming_call(call->core,call);
}
- ortp_event_destroy(ev);
}
+ ortp_event_destroy(ev);
}
}
#endif
if (call->audiostream!=NULL) {
+ OrtpEvent *ev;
+
// Beware that the application queue should not depend on treatments fron the
// mediastreamer queue.
audio_stream_iterate(call->audiostream);
- if (call->audiostream_app_evq){
- OrtpEvent *ev;
- while (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq))){
- OrtpEventType evt=ortp_event_get_type(ev);
- OrtpEventData *evd=ortp_event_get_data(ev);
- if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
- linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
- } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) {
- linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified);
- } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
- call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->session);
- if(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp != NULL)
- freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp);
- call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp = evd->packet;
- evd->packet = NULL;
- if (lc->vtable.call_stats_updated)
- lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
- } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
- memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->session), sizeof(jitter_stats_t));
- if(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp != NULL)
- freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp);
- call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp = evd->packet;
- evd->packet = NULL;
- if (lc->vtable.call_stats_updated)
- lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
- } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
- if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) {
- linphone_core_update_call(lc, call, &call->current_params);
- }
- } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
- if (call->state==LinphoneCallOutgoingInit) {
- linphone_call_stop_media_streams(call);
- if (evd->info.ice_processing_successful==FALSE) {
- ice_session_destroy(sal_op_get_ice_session(call->op));
- sal_op_set_ice_session(call->op, NULL);
- }
- linphone_core_start_invite(call->core,call,NULL);
- }
+ while (call->audiostream_app_evq && (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq)))){
+ OrtpEventType evt=ortp_event_get_type(ev);
+ OrtpEventData *evd=ortp_event_get_data(ev);
+ if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){
+ linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted);
+ } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) {
+ linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified);
+ } else if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED) {
+ call->stats[LINPHONE_CALL_STATS_AUDIO].round_trip_delay = rtp_session_get_round_trip_propagation(call->audiostream->session);
+ if(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp != NULL)
+ freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp);
+ call->stats[LINPHONE_CALL_STATS_AUDIO].received_rtcp = evd->packet;
+ evd->packet = NULL;
+ if (lc->vtable.call_stats_updated)
+ lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
+ } else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
+ memcpy(&call->stats[LINPHONE_CALL_STATS_AUDIO].jitter_stats, rtp_session_get_jitter_stats(call->audiostream->session), sizeof(jitter_stats_t));
+ if(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp != NULL)
+ freemsg(call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp);
+ call->stats[LINPHONE_CALL_STATS_AUDIO].sent_rtcp = evd->packet;
+ evd->packet = NULL;
+ if (lc->vtable.call_stats_updated)
+ lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
+ } else if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) {
+ if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) {
+ linphone_core_update_call(lc, call, &call->current_params);
+ }
+ } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) {
+ IceSession *ice_session = sal_op_get_ice_session(call->op);
+ linphone_call_stop_media_streams(call);
+ if (evd->info.ice_processing_successful==TRUE) {
+ ice_session_compute_candidates_foundations(ice_session);
+ ice_session_eliminate_redundant_candidates(ice_session);
+ ice_session_choose_default_candidates(ice_session);
+ } else {
+ ice_session_destroy(sal_op_get_ice_session(call->op));
+ sal_op_set_ice_session(call->op, NULL);
+ }
+ if (call->state==LinphoneCallOutgoingInit) {
+ linphone_core_start_invite(call->core,call,NULL);
+ } else {
+ linphone_core_notify_incoming_call(call->core,call);
}
- ortp_event_destroy(ev);
}
+ ortp_event_destroy(ev);
}
}
if (call->state==LinphoneCallStreamsRunning && one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 )
return FALSE;
}
+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);
+
+ /* Regenerate final media description to include all ICE candidates. */
+ md=sal_call_get_final_media_description(call->op);
+
+ if (md && sal_media_description_empty(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);
+
+ /* 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...");
+ 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_tone(lc);
+ }
+
+ linphone_call_set_state(call,LinphoneCallIncomingReceived,"Incoming call");
+
+ if (call->state==LinphoneCallIncomingReceived){
+ 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);
+}
+
/**
* @ingroup call_control
* Updates a running call according to supplied call parameters or parameters changed in the LinphoneCore.