diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 1f7ff42fd..7985f3658 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -345,6 +345,7 @@ static void call_accepted(SalOp *op){ if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call); } if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){ + linphone_call_update_remote_session_id_and_ver(call); if (sal_media_description_has_dir(md,SalStreamSendOnly) || sal_media_description_has_dir(md,SalStreamInactive)){ if (lc->vtable.display_status){ @@ -425,6 +426,7 @@ static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){ linphone_core_update_ice_from_remote_media_description(call,rmd); linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session); } + linphone_call_update_remote_session_id_and_ver(call); sal_call_accept(call->op); md=sal_call_get_final_media_description(call->op); if (md && !sal_media_description_empty(md)) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4465d6f8e..6ef8e0c55 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1708,6 +1708,14 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript #endif } +void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call) { + SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op); + if (remote_desc) { + call->remote_session_id = remote_desc->session_id; + call->remote_session_ver = remote_desc->session_ver; + } +} + void linphone_call_delete_ice_session(LinphoneCall *call){ if (call->ice_session != NULL) { ice_session_destroy(call->ice_session); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ee0be33be..28488e1dd 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2739,6 +2739,7 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call) } linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session); } + linphone_call_update_remote_session_id_and_ver(call); sal_call_set_local_media_description(call->op,call->localdesc); sal_call_accept(call->op); md=sal_call_get_final_media_description(call->op); @@ -2768,6 +2769,8 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call) * @return 0 if sucessful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state). **/ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){ + SalMediaDescription *remote_desc; + bool_t keep_sdp_version; #ifdef VIDEO_ENABLED bool_t old_has_video = call->params.has_video; #endif @@ -2776,6 +2779,15 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const linphone_call_state_to_string(call->state)); return -1; } + remote_desc = sal_call_get_remote_media_description(call->op); + keep_sdp_version = lp_config_get_int(lc->config, "sip", "keep_sdp_version", 0); + if (keep_sdp_version &&(remote_desc->session_id == call->remote_session_id) && (remote_desc->session_ver == call->remote_session_ver)) { + /* Remote has sent an INVITE with the same SDP as before, so send a 200 OK with the same SDP as before. */ + ms_warning("SDP version has not changed, send same SDP as before."); + sal_call_accept(call->op); + linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)"); + return 0; + } if (params==NULL){ call->params.has_video=lc->video_policy.automatically_accept || call->current_params.has_video; }else @@ -2789,11 +2801,11 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const ms_warning("Video isn't supported in conference"); call->params.has_video = FALSE; } - call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op)); + call->params.has_video &= linphone_core_media_description_contains_video_stream(remote_desc); call->camera_active=call->params.has_video; linphone_call_make_local_media_description(lc,call); if (call->ice_session != NULL) { - linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(call->op)); + linphone_core_update_ice_from_remote_media_description(call, remote_desc); #ifdef VIDEO_ENABLED if ((call->ice_session != NULL) &&!ice_session_candidates_gathered(call->ice_session)) { if ((call->params.has_video) && (call->params.has_video != old_has_video)) { @@ -2920,6 +2932,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard); } + linphone_call_update_remote_session_id_and_ver(call); sal_call_accept(call->op); if (lc->vtable.display_status!=NULL) lc->vtable.display_status(lc,_("Connected.")); diff --git a/coreapi/private.h b/coreapi/private.h index 29d31b7c6..5c09974b7 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -148,6 +148,8 @@ struct _LinphoneCall IceSession *ice_session; LinphoneChatMessage* pending_message; int ping_time; + unsigned int remote_session_id; + unsigned int remote_session_ver; bool_t refer_pending; bool_t media_pending; bool_t audio_muted; @@ -286,6 +288,7 @@ void linphone_call_stop_media_streams(LinphoneCall *call); void linphone_call_delete_ice_session(LinphoneCall *call); void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call); void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md); +void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call); const char * linphone_core_get_identity(LinphoneCore *lc); const char * linphone_core_get_route(LinphoneCore *lc); diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index 050a53a76..4aad14863 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -434,10 +434,17 @@ static int payload_type_fill_from_rtpmap(PayloadType *pt, const char *rtpmap){ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){ int i,j; const char *mtype,*proto,*rtp_port,*rtp_addr,*number; + const char *sess; sdp_bandwidth_t *sbw=NULL; sdp_attribute_t *attr; int nb_ice_candidates; + /* Get session information. */ + sess = sdp_message_o_sess_id_get(msg); + if (sess) desc->session_id = strtoul(sess, NULL, 10); + sess = sdp_message_o_sess_version_get(msg); + if (sess) desc->session_ver = strtoul(sess, NULL, 10); + rtp_addr=sdp_message_c_addr_get (msg, -1, 0); if (rtp_addr) strncpy(desc->addr,rtp_addr,sizeof(desc->addr));