diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index dd17650f5..63327de66 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -187,7 +187,7 @@ static void call_received(SalOp *h){ 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) && sal_op_get_ice_session(call->op)) { + 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; @@ -254,7 +254,6 @@ static void call_ringing(SalOp *h){ static void call_accepted(SalOp *op){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); - IceSession *ice_session=sal_op_get_ice_session(op); SalMediaDescription *md; if (call==NULL){ @@ -262,7 +261,7 @@ static void call_accepted(SalOp *op){ return ; } - if (ice_session == NULL) { + if (call->ice_session == NULL) { /* Ensure the ICE check list pointers for the call streams are resetted to prevent crashes */ if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ice_check_list = NULL; diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index d8fcb12c9..4a06a7873 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -201,7 +201,6 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li LinphoneAddress *addr=linphone_address_new(me); const char *username=linphone_address_get_username (addr); SalMediaDescription *md=sal_media_description_new(); - IceSession *ice_session=sal_op_get_ice_session(call->op); md->session_id=session_id; md->session_ver=session_ver; @@ -249,8 +248,8 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li md->streams[i].crypto[2].algo = 0; } if ((call->dir == LinphoneCallOutgoing) && (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) - && (ice_session != NULL) && (ice_session_check_list(ice_session, i) == NULL)) { - ice_session_add_check_list(ice_session, ice_check_list_new()); + && (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, i) == NULL)) { + ice_session_add_check_list(call->ice_session, ice_check_list_new()); } } @@ -346,8 +345,8 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr linphone_call_init_common(call,from,to); call->params=*params; if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) { - sal_op_set_ice_session(call->op, ice_session_new()); - ice_session_set_role(sal_op_get_ice_session(call->op), IR_Controlling); + call->ice_session = ice_session_new(); + ice_session_set_role(call->ice_session, IR_Controlling); } call->localdesc=create_local_media_description (lc,call); call->camera_active=params->has_video; @@ -403,9 +402,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_core_run_stun_tests(call->core,call); /* No break to also destroy ice session in this case. */ default: - if (sal_op_get_ice_session(call->op) != NULL) { - linphone_call_delete_ice_session(call); - } + linphone_call_delete_ice_session(call); break; } discover_mtu(lc,linphone_address_get_domain(from)); @@ -552,11 +549,10 @@ void linphone_call_enable_video(LinphoneCall *call, bool_t enabled) { LinphoneCore *lc=linphone_call_get_core(call); LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call)); - IceSession *ice_session=sal_op_get_ice_session(call->op); linphone_call_params_enable_video(params, enabled); if (enabled == TRUE) { - if (ice_session != NULL) { + if (call->ice_session != NULL) { /* Defer call update until the ICE candidates gathering process has finished. */ ms_message("Defer call update to gather ICE candidates"); call->params = *params; @@ -572,8 +568,8 @@ void linphone_call_enable_video(LinphoneCall *call, bool_t enabled) } } } else { - if ((ice_session != NULL) && (call->videostream != NULL)) { - ice_session_remove_check_list(ice_session, call->videostream->ice_check_list); + if ((call->ice_session != NULL) && (call->videostream != NULL)) { + ice_session_remove_check_list(call->ice_session, call->videostream->ice_check_list); call->videostream->ice_check_list = NULL; } if (linphone_call_get_state(call) == LinphoneCallUpdatedByRemote) { @@ -610,6 +606,9 @@ static void linphone_call_destroy(LinphoneCall *obj) if (obj->auth_token) { ms_free(obj->auth_token); } + if (obj->ice_session) { + ice_session_destroy(obj->ice_session); + } ms_free(obj); } @@ -971,7 +970,6 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ LinphoneCore *lc=call->core; SalMediaDescription *md=call->localdesc; AudioStream *audiostream; - IceSession *ice_session = sal_op_get_ice_session(call->op); call->audiostream=audiostream=audio_stream_new(md->streams[0].rtp_port,md->streams[0].rtcp_port,linphone_core_ipv6_enabled(lc)); if (linphone_core_echo_limiter_enabled(lc)){ @@ -1004,9 +1002,9 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ RtpTransport *artcp=lc->rtptf->audio_rtcp_func(lc->rtptf->audio_rtcp_func_data, call->audio_port+1); rtp_session_set_transports(audiostream->session,artp,artcp); } - if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (ice_session != NULL)){ + if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)){ rtp_session_set_pktinfo(audiostream->session, TRUE); - audiostream->ice_check_list = ice_session_check_list(ice_session, 0); + audiostream->ice_check_list = ice_session_check_list(call->ice_session, 0); ice_check_list_set_rtp_session(audiostream->ice_check_list, audiostream->session); } @@ -1018,7 +1016,6 @@ void linphone_call_init_video_stream(LinphoneCall *call){ #ifdef VIDEO_ENABLED LinphoneCore *lc=call->core; SalMediaDescription *md=call->localdesc; - IceSession *ice_session = sal_op_get_ice_session(call->op); if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].rtp_port>0){ int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0); @@ -1034,9 +1031,9 @@ void linphone_call_init_video_stream(LinphoneCall *call){ RtpTransport *vrtcp=lc->rtptf->video_rtcp_func(lc->rtptf->video_rtcp_func_data, call->video_port+1); rtp_session_set_transports(call->videostream->session,vrtp,vrtcp); } - if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (ice_session != NULL) && (ice_session_check_list(ice_session, 1))){ + if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, 1))){ rtp_session_set_pktinfo(call->videostream->session, TRUE); - call->videostream->ice_check_list = ice_session_check_list(ice_session, 1); + call->videostream->ice_check_list = ice_session_check_list(call->ice_session, 1); ice_check_list_set_rtp_session(call->videostream->ice_check_list, call->videostream->session); } call->videostream_app_evq = ortp_ev_queue_new(); @@ -1495,8 +1492,8 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut /*also reflect the change if the "wished" params, in order to avoid to propose SAVP or video again * further in the call, for example during pause,resume, conferencing reINVITEs*/ linphone_call_fix_call_parameters(call); - if ((sal_op_get_ice_session(call->op) != NULL) && (ice_session_state(sal_op_get_ice_session(call->op)) != IS_Completed)) { - ice_session_start_connectivity_checks(sal_op_get_ice_session(call->op)); + if ((call->ice_session != NULL) && (ice_session_state(call->ice_session) != IS_Completed)) { + ice_session_start_connectivity_checks(call->ice_session); } goto end; @@ -1513,10 +1510,9 @@ void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call){ } void linphone_call_delete_ice_session(LinphoneCall *call){ - IceSession *ice_session = sal_op_get_ice_session(call->op); - if (ice_session != NULL) { - ice_session_destroy(ice_session); - sal_op_set_ice_session(call->op, NULL); + if (call->ice_session != NULL) { + ice_session_destroy(call->ice_session); + call->ice_session = NULL; if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ice_check_list = NULL; } @@ -1739,19 +1735,18 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ OrtpEventData *evd=ortp_event_get_data(ev); if (evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) { - if (ice_session_role(sal_op_get_ice_session(call->op)) == IR_Controlling) { + if (ice_session_role(call->ice_session) == IR_Controlling) { linphone_core_update_call(call->core, call, &call->current_params); } } else if (evt == ORTP_EVENT_ICE_GATHERING_FINISHED) { - IceSession *ice_session = sal_op_get_ice_session(call->op); LinphoneCallParams *params; switch (call->state) { case LinphoneCallStreamsRunning: case LinphoneCallUpdatedByRemote: 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); + ice_session_compute_candidates_foundations(call->ice_session); + ice_session_eliminate_redundant_candidates(call->ice_session); + ice_session_choose_default_candidates(call->ice_session); } params = linphone_call_params_copy(linphone_call_get_current_params(call)); linphone_call_params_enable_video(params, TRUE); @@ -1766,9 +1761,9 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){ default: 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); + ice_session_compute_candidates_foundations(call->ice_session); + ice_session_eliminate_redundant_candidates(call->ice_session); + ice_session_choose_default_candidates(call->ice_session); } else { linphone_call_delete_ice_session(call); } @@ -1808,7 +1803,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse OrtpEvent *ev; /* Ensure there is no dangling ICE check list. */ - if (sal_op_get_ice_session(call->op) == NULL) call->videostream->ice_check_list = NULL; + if (call->ice_session == NULL) call->videostream->ice_check_list = NULL; // Beware that the application queue should not depend on treatments fron the // mediastreamer queue. @@ -1846,7 +1841,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse OrtpEvent *ev; /* Ensure there is no dangling ICE check list. */ - if (sal_op_get_ice_session(call->op) == NULL) call->audiostream->ice_check_list = NULL; + if (call->ice_session == NULL) call->audiostream->ice_check_list = NULL; // Beware that the application queue should not depend on treatments fron the // mediastreamer queue. diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 921e1800e..6f08e9260 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1852,7 +1852,7 @@ void linphone_core_iterate(LinphoneCore *lc){ linphone_call_background_tasks(call,one_second_elapsed); if (call->state==LinphoneCallOutgoingInit && (curtime-call->start_time>=2)){ /*start the call even if the OPTIONS reply did not arrive*/ - if (sal_op_get_ice_session(call->op) != NULL) { + if (call->ice_session != NULL) { /* ICE candidates gathering has not finished yet, proceed with the call without ICE anyway. */ linphone_call_delete_ice_session(call); linphone_call_stop_media_streams(call); diff --git a/coreapi/misc.c b/coreapi/misc.c index 0e4be8e11..a59aca886 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -569,12 +569,11 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) socklen_t ss_len; IceCheckList *audio_check_list; IceCheckList *video_check_list; - IceSession *ice_session = sal_op_get_ice_session(call->op); const char *server = linphone_core_get_stun_server(lc); - if ((server == NULL) || (ice_session == NULL)) return -1; - audio_check_list = ice_session_check_list(ice_session, 0); - video_check_list = ice_session_check_list(ice_session, 1); + if ((server == NULL) || (call->ice_session == NULL)) return -1; + audio_check_list = ice_session_check_list(call->ice_session, 0); + video_check_list = ice_session_check_list(call->ice_session, 1); if (audio_check_list == NULL) return -1; if (lc->sip_conf.ipv6_enabled){ @@ -602,7 +601,7 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call) } /* Gather local srflx candidates. */ - ice_session_gather_candidates(ice_session, ss, ss_len); + ice_session_gather_candidates(call->ice_session, ss, ss_len); return 0; } diff --git a/coreapi/private.h b/coreapi/private.h index 61d1d4179..bc65e946e 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -136,6 +136,7 @@ struct _LinphoneCall bool_t was_automatically_paused; CallCallbackObj nextVideoFrameDecoded; LinphoneCallStats stats[2]; + IceSession *ice_session; }; diff --git a/coreapi/sal.c b/coreapi/sal.c index 5b592b8d3..a7bb00e3e 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -234,10 +234,6 @@ void sal_op_set_user_pointer(SalOp *op, void *up){ ((SalOpBase*)op)->user_pointer=up; } -void sal_op_set_ice_session(SalOp *op, IceSession *ice_session){ - ((SalOpBase*)op)->ice_session=ice_session; -} - Sal *sal_op_get_sal(const SalOp *op){ return ((SalOpBase*)op)->root; } @@ -266,10 +262,6 @@ void *sal_op_get_user_pointer(const SalOp *op){ return ((SalOpBase*)op)->user_pointer; } -IceSession *sal_op_get_ice_session(const SalOp *op){ - return ((SalOpBase*)op)->ice_session; -} - const char *sal_op_get_proxy(const SalOp *op){ return ((SalOpBase*)op)->route; } @@ -318,8 +310,6 @@ void __sal_op_free(SalOp *op){ sal_media_description_unref(b->local_media); if (b->remote_media) sal_media_description_unref(b->remote_media); - if (b->ice_session) - ice_session_destroy(b->ice_session); ms_free(op); } diff --git a/coreapi/sal.h b/coreapi/sal.h index 8a51fa4a4..dfb560472 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define sal_h #include "mediastreamer2/mscommon.h" -#include "mediastreamer2/ice.h" #include "ortp/ortp_srtp.h" /*Dirty hack, keep in sync with mediastreamer2/include/mediastream.h */ @@ -113,6 +112,33 @@ typedef struct SalEndpointCandidate{ #define SAL_ENDPOINT_CANDIDATE_MAX 2 +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN 64 +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_FOUNDATION_LEN 32 +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_TYPE_LEN 6 + +typedef struct SalIceCandidate { + char addr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN]; + char raddr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN]; + char foundation[SAL_MEDIA_DESCRIPTION_MAX_ICE_FOUNDATION_LEN]; + char type[SAL_MEDIA_DESCRIPTION_MAX_ICE_TYPE_LEN]; + unsigned int componentID; + unsigned int priority; + int port; + int rport; +} SalIceCandidate; + +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES 10 + +typedef struct SalIceRemoteCandidate { + char addr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN]; + int port; +} SalIceRemoteCandidate; + +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES 2 + +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256 +#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256 + typedef struct SalSrtpCryptoAlgo { unsigned int tag; enum ortp_srtp_crypto_suite_t algo; @@ -138,6 +164,11 @@ typedef struct SalStreamDescription{ SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX]; unsigned int crypto_local_tag; int max_rate; + SalIceCandidate ice_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES]; + SalIceRemoteCandidate ice_remote_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES]; + char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN]; + char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN]; + bool_t ice_mismatch; } SalStreamDescription; #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4 @@ -151,10 +182,13 @@ typedef struct SalMediaDescription{ unsigned int session_ver; unsigned int session_id; SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS]; + char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN]; + char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN]; + bool_t ice_lite; + bool_t ice_completed; } SalMediaDescription; #define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5 -#define SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES 10 SalMediaDescription *sal_media_description_new(); void sal_media_description_ref(SalMediaDescription *md); @@ -177,7 +211,6 @@ typedef struct SalOpBase{ char *remote_ua; SalMediaDescription *local_media; SalMediaDescription *remote_media; - IceSession *ice_session; void *user_pointer; } SalOpBase; @@ -322,7 +355,6 @@ void sal_op_release(SalOp *h); void sal_op_authenticate(SalOp *h, const SalAuthInfo *info); void sal_op_cancel_authentication(SalOp *h); void sal_op_set_user_pointer(SalOp *h, void *up); -void sal_op_set_ice_session(SalOp *h, IceSession *ice_session); int sal_op_get_auth_requested(SalOp *h, const char **realm, const char **username); const char *sal_op_get_from(const SalOp *op); const char *sal_op_get_to(const SalOp *op); @@ -334,7 +366,6 @@ const char *sal_op_get_network_origin(const SalOp *op); /*returns far-end "User-Agent" string */ const char *sal_op_get_remote_ua(const SalOp *op); void *sal_op_get_user_pointer(const SalOp *op); -IceSession *sal_op_get_ice_session(const SalOp *op); /*Call API*/ int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 42f11eca0..a9f3559b6 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -502,8 +502,8 @@ static void set_sdp(osip_message_t *sip,sdp_message_t *msg){ osip_free(sdp); } -static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc, const IceSession *ice_session){ - sdp_message_t *msg=media_description_to_sdp(desc, ice_session); +static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){ + sdp_message_t *msg=media_description_to_sdp(desc); if (msg==NULL) { ms_error("Fail to print sdp message !"); return; @@ -526,7 +526,7 @@ static void sdp_process(SalOp *h){ sdp_message_free(h->sdp_answer); } offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec); - h->sdp_answer=media_description_to_sdp(h->result, sal_op_get_ice_session(h)); + h->sdp_answer=media_description_to_sdp(h->result); /*once we have generated the SDP answer, we modify the result description for processing by the upper layer. It should contains media parameters constraint from the remote offer, not our response*/ strcpy(h->result->addr,h->base.remote_media->addr); @@ -600,7 +600,7 @@ int sal_call(SalOp *h, const char *from, const char *to){ } if (h->base.local_media){ h->sdp_offering=TRUE; - set_sdp_from_desc(invite,h->base.local_media,sal_op_get_ice_session(h)); + set_sdp_from_desc(invite,h->base.local_media); }else h->sdp_offering=FALSE; if (h->replaces){ osip_message_set_header(invite,"Replaces",h->replaces); @@ -668,7 +668,7 @@ int sal_call_accept(SalOp * h){ if (h->base.local_media){ /*this is the case where we received an invite without SDP*/ if (h->sdp_offering) { - set_sdp_from_desc(msg,h->base.local_media,sal_op_get_ice_session(h)); + set_sdp_from_desc(msg,h->base.local_media); }else{ if (h->sdp_answer==NULL) sdp_process(h); if (h->sdp_answer){ @@ -990,7 +990,6 @@ static void inc_new_call(Sal *sal, eXosip_event_t *ev){ osip_call_info_t *call_info; char *tmp; sdp_message_t *sdp=eXosip_get_sdp_info(ev->request); - IceSession *ice_session; set_network_origin(op,ev->request); set_remote_ua(op,ev->request); @@ -999,9 +998,7 @@ static void inc_new_call(Sal *sal, eXosip_event_t *ev){ if (sdp){ op->sdp_offering=FALSE; op->base.remote_media=sal_media_description_new(); - ice_session=sal_op_get_ice_session(op); - sdp_to_media_description(sdp,op->base.remote_media,&ice_session); - sal_op_set_ice_session(op,ice_session); + sdp_to_media_description(sdp,op->base.remote_media); sdp_message_free(sdp); }else op->sdp_offering=TRUE; @@ -1037,7 +1034,6 @@ static void inc_new_call(Sal *sal, eXosip_event_t *ev){ static void handle_reinvite(Sal *sal, eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); sdp_message_t *sdp; - IceSession *ice_session; if (op==NULL) { ms_warning("Reinvite for non-existing operation !"); @@ -1057,9 +1053,7 @@ static void handle_reinvite(Sal *sal, eXosip_event_t *ev){ if (sdp){ op->sdp_offering=FALSE; op->base.remote_media=sal_media_description_new(); - ice_session=sal_op_get_ice_session(op); - sdp_to_media_description(sdp,op->base.remote_media,&ice_session); - sal_op_set_ice_session(op,ice_session); + sdp_to_media_description(sdp,op->base.remote_media); sdp_message_free(sdp); }else { @@ -1071,7 +1065,6 @@ static void handle_reinvite(Sal *sal, eXosip_event_t *ev){ static void handle_ack(Sal *sal, eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); sdp_message_t *sdp; - IceSession *ice_session; if (op==NULL) { ms_warning("ack for non-existing call !"); @@ -1088,9 +1081,7 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){ if (op->base.remote_media) sal_media_description_unref(op->base.remote_media); op->base.remote_media=sal_media_description_new(); - ice_session=sal_op_get_ice_session(op); - sdp_to_media_description(sdp,op->base.remote_media,&ice_session); - sal_op_set_ice_session(op,ice_session); + sdp_to_media_description(sdp,op->base.remote_media); sdp_process(op); sdp_message_free(sdp); } @@ -1150,16 +1141,13 @@ static int call_proceeding(Sal *sal, eXosip_event_t *ev){ static void call_ringing(Sal *sal, eXosip_event_t *ev){ sdp_message_t *sdp; SalOp *op=find_op(sal,ev); - IceSession *ice_session; if (call_proceeding(sal, ev)==-1) return; set_remote_ua(op,ev->response); sdp=eXosip_get_sdp_info(ev->response); if (sdp){ op->base.remote_media=sal_media_description_new(); - ice_session=sal_op_get_ice_session(op); - sdp_to_media_description(sdp,op->base.remote_media,&ice_session); - sal_op_set_ice_session(op,ice_session); + sdp_to_media_description(sdp,op->base.remote_media); sdp_message_free(sdp); if (op->base.local_media) sdp_process(op); } @@ -1171,7 +1159,6 @@ static void call_accepted(Sal *sal, eXosip_event_t *ev){ osip_message_t *msg=NULL; SalOp *op=find_op(sal,ev); const char *contact; - IceSession *ice_session; if (op==NULL || op->terminated==TRUE) { ms_warning("This call has been already terminated."); @@ -1187,9 +1174,7 @@ static void call_accepted(Sal *sal, eXosip_event_t *ev){ sdp=eXosip_get_sdp_info(ev->response); if (sdp){ op->base.remote_media=sal_media_description_new(); - ice_session=sal_op_get_ice_session(op); - sdp_to_media_description(sdp,op->base.remote_media,&ice_session); - sal_op_set_ice_session(op,ice_session); + sdp_to_media_description(sdp,op->base.remote_media); sdp_message_free(sdp); if (op->base.local_media) sdp_process(op); } @@ -2427,7 +2412,7 @@ int sal_call_update(SalOp *h, const char *subject){ } if (h->base.local_media){ h->sdp_offering=TRUE; - set_sdp_from_desc(reinvite,h->base.local_media,sal_op_get_ice_session(h)); + set_sdp_from_desc(reinvite,h->base.local_media); }else h->sdp_offering=FALSE; eXosip_lock(); err = eXosip_call_send_request(h->did, reinvite); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index e3264f74d..ccc95d56a 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -25,8 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -sdp_message_t *media_description_to_sdp(const SalMediaDescription *sal, const IceSession *ice_session); -int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc, IceSession **ice_session); +sdp_message_t *media_description_to_sdp(const SalMediaDescription *sal); +int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc); struct Sal{ SalCallbacks callbacks; diff --git a/coreapi/sal_eXosip2_sdp.c b/coreapi/sal_eXosip2_sdp.c index 1cd88cad7..e03e65bae 100644 --- a/coreapi/sal_eXosip2_sdp.c +++ b/coreapi/sal_eXosip2_sdp.c @@ -124,7 +124,7 @@ static int _sdp_message_get_mline_dir(sdp_message_t *sdp, int mline){ return SalStreamSendRecv; } -static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc, const IceSession *ice_session) +static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc) { sdp_message_t *local; int inet6; @@ -144,14 +144,6 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc, const osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"), osip_strdup (desc->addr)); sdp_message_s_name_set (local, osip_strdup ("Talk")); - if ((ice_session != NULL) && (ice_session_check_list(ice_session, 0) != NULL)) { - if (ice_session_state(ice_session) == IS_Completed) { - ice_check_list_nominated_valid_local_candidate(ice_session_check_list(ice_session, 0), &rtp_addr, NULL, NULL, NULL); - } - else { - ice_check_list_default_local_candidate(ice_session_check_list(ice_session, 0), &rtp_addr, NULL, NULL, NULL); - } - } if(!sal_media_description_has_dir (desc,SalStreamSendOnly)) { sdp_message_c_connection_add (local, -1, @@ -167,23 +159,9 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc, const sdp_message_t_time_descr_add (local, osip_strdup ("0"), osip_strdup ("0")); if (desc->bandwidth>0) sdp_message_b_bandwidth_add (local, -1, osip_strdup ("AS"), int_2char(desc->bandwidth)); - if ((ice_session != NULL) && (ice_session_check_list(ice_session, 0) != NULL)) { - char buffer[512]; - switch (ice_session_state(ice_session)) { - case IS_Completed: - sdp_message_a_attribute_add(local, -1, osip_strdup("nortpproxy"), osip_strdup("yes")); - /* No break to also include the ice-ufrag and ice-pwd attributes when ICE session is completed. */ - case IS_Running: - case IS_Stopped: - snprintf(buffer, sizeof(buffer), "%s", ice_session_local_pwd(ice_session)); - sdp_message_a_attribute_add(local, -1, osip_strdup("ice-pwd"), osip_strdup(buffer)); - snprintf(buffer, sizeof(buffer), "%s", ice_session_local_ufrag(ice_session)); - sdp_message_a_attribute_add(local, -1, osip_strdup("ice-ufrag"), osip_strdup(buffer)); - break; - default: - break; - } - } + if (desc->ice_completed == TRUE) sdp_message_a_attribute_add(local, -1, osip_strdup("nortpproxy"), osip_strdup("yes")); + if (desc->ice_pwd[0] != '\0') sdp_message_a_attribute_add(local, -1, osip_strdup("ice-pwd"), osip_strdup(desc->ice_pwd)); + if (desc->ice_ufrag[0] != '\0') sdp_message_a_attribute_add(local, -1, osip_strdup("ice-ufrag"), osip_strdup(desc->ice_ufrag)); return local; } @@ -224,83 +202,57 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt, boo } } -static void add_candidate_attribute(sdp_message_t *msg, int lineno, const IceCandidate *candidate) +static void add_ice_candidates(sdp_message_t *msg, int lineno, const SalStreamDescription *desc) { char buffer[1024]; + const SalIceCandidate *candidate; int nb; + int i; - nb = snprintf(buffer, sizeof(buffer), "%s %d UDP %d %s %d typ %s", - candidate->foundation, candidate->componentID, candidate->priority, candidate->taddr.ip, candidate->taddr.port, ice_candidate_type(candidate)); - if (nb < 0) { - ms_error("Cannot add ICE candidate attribute!"); - return; - } - if (candidate->type != ICT_HostCandidate) { - nb = snprintf(buffer + nb, sizeof(buffer) - nb, " raddr %s rport %d", candidate->base->taddr.ip, candidate->base->taddr.port); + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; i++) { + candidate = &desc->ice_candidates[i]; + if ((candidate->addr[0] == '\0') || (candidate->port == 0)) break; + nb = snprintf(buffer, sizeof(buffer), "%s %u UDP %u %s %d typ %s", + candidate->foundation, candidate->componentID, candidate->priority, candidate->addr, candidate->port, candidate->type); if (nb < 0) { ms_error("Cannot add ICE candidate attribute!"); return; } - } - sdp_message_a_attribute_add(msg, lineno, osip_strdup("candidate"), osip_strdup(buffer)); -} - -static void add_ice_candidates(sdp_message_t *msg, int lineno, const IceCheckList *ice_cl, const char *rtp_addr, int rtp_port, const char *rtcp_addr, int rtcp_port) -{ - const IceCandidate *candidate; - int i; - - if ((ice_check_list_state(ice_cl) == ICL_Failed) && ice_check_list_is_mismatch(ice_cl)) { - sdp_message_a_attribute_add(msg, lineno, osip_strdup("ice-mismatch"), NULL); - return; - } - for (i = 0; i < ms_list_size(ice_cl->local_candidates); i++) { - candidate = ms_list_nth_data(ice_cl->local_candidates, i); - switch (ice_check_list_state(ice_cl)) { - case ICL_Running: - add_candidate_attribute(msg, lineno, candidate); - break; - case ICL_Completed: - /* Only include the candidates matching the default destination for each component of the stream as specified in RFC5245 section 9.1.2.2. */ - if (((candidate->taddr.port == rtp_port) && (strlen(candidate->taddr.ip) == strlen(rtp_addr)) && (strcmp(candidate->taddr.ip, rtp_addr) == 0)) - || ((candidate->taddr.port == rtcp_port) && (strlen(candidate->taddr.ip) == strlen(rtcp_addr)) && (strcmp(candidate->taddr.ip, rtcp_addr) == 0))) { - add_candidate_attribute(msg, lineno, candidate); - } - break; - default: - break; - } - } -} - -static void add_ice_remote_candidates(sdp_message_t *msg, int lineno, const IceCheckList *ice_cl) -{ - char buffer[1024]; - const char *rtp_addr = NULL; - const char *rtcp_addr = NULL; - int rtp_port; - int rtcp_port; - int nb; - - if ((ice_session_role(ice_cl->session) == IR_Controlling) && (ice_check_list_state(ice_cl) == ICL_Completed)) { - ice_check_list_nominated_valid_remote_candidate(ice_cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); - nb = snprintf(buffer, sizeof(buffer), "1 %s %d", rtp_addr, rtp_port); - if (nb < 0) { - ms_error("Cannot add ICE remote-candidates attribute!"); - return; - } - if (rtcp_addr != NULL) { - nb = snprintf(buffer + nb, sizeof(buffer) - nb, " 2 %s %d", rtcp_addr, rtcp_port); + if (candidate->raddr[0] != '\0') { + nb = snprintf(buffer + nb, sizeof(buffer) - nb, " raddr %s rport %d", candidate->raddr, candidate->rport); if (nb < 0) { - ms_error("Cannot add ICE remote-candidates attribute!"); + ms_error("Cannot add ICE candidate attribute!"); return; } } - sdp_message_a_attribute_add(msg, lineno, osip_strdup("remote-candidates"), osip_strdup(buffer)); + sdp_message_a_attribute_add(msg, lineno, osip_strdup("candidate"), osip_strdup(buffer)); } } -static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc, const IceCheckList *ice_cl){ +static void add_ice_remote_candidates(sdp_message_t *msg, int lineno, const SalStreamDescription *desc) +{ + char buffer[1024]; + char *ptr = buffer; + const SalIceRemoteCandidate *candidate; + int offset = 0; + int i; + + buffer[0] = '\0'; + for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES; i++) { + candidate = &desc->ice_remote_candidates[i]; + if ((candidate->addr[0] != '\0') && (candidate->port != 0)) { + offset = snprintf(ptr, buffer + sizeof(buffer) - ptr, "%s%d %s %d", (i > 0) ? " " : "", i + 1, candidate->addr, candidate->port); + if (offset < 0) { + ms_error("Cannot add ICE remote-candidates attribute!"); + return; + } + ptr += offset; + } + } + if (buffer[0] != '\0') sdp_message_a_attribute_add(msg, lineno, osip_strdup("remote-candidates"), osip_strdup(buffer)); +} + +static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){ const char *mt=NULL; const MSList *elem; const char *rtp_addr; @@ -309,6 +261,7 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription int rtp_port; int rtcp_port; bool_t strip_well_known_rtpmaps; + bool_t different_rtp_and_rtcp_addr; switch (desc->type) { case SalAudio: @@ -321,16 +274,11 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription mt=desc->typeother; break; } - rtp_addr=rtcp_addr=desc->rtp_addr; + rtp_addr=desc->rtp_addr; + rtcp_addr=desc->rtcp_addr; rtp_port=desc->rtp_port; rtcp_port=desc->rtcp_port; - if (ice_cl != NULL) { - if (ice_check_list_state(ice_cl) == ICL_Completed) { - ice_check_list_nominated_valid_local_candidate(ice_cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); - } else { - ice_check_list_default_local_candidate(ice_cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port); - } - } else if (desc->candidates[0].addr[0]!='\0'){ + if (desc->candidates[0].addr[0]!='\0'){ rtp_addr=desc->candidates[0].addr; rtp_port=desc->candidates[0].port; } @@ -417,28 +365,34 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription break; } if (dir) sdp_message_a_attribute_add (msg, lineno, osip_strdup (dir),NULL); - if (ice_cl != NULL) { - if (strcmp(rtp_addr, rtcp_addr) != 0) { - char buffer[1024]; - snprintf(buffer, sizeof(buffer), "%u IN IP4 %s", rtcp_port, rtcp_addr); - sdp_message_a_attribute_add(msg, lineno, osip_strdup("rtcp"), osip_strdup(buffer)); - } else { - sdp_message_a_attribute_add(msg, lineno, osip_strdup("rtcp"), int_2char(rtcp_port)); + if (rtp_port != 0) { + different_rtp_and_rtcp_addr = (rtcp_addr[0] != '\0') && (strcmp(rtp_addr, rtcp_addr) != 0); + if ((rtcp_port != (rtp_port + 1)) || (different_rtp_and_rtcp_addr == TRUE)) { + if (different_rtp_and_rtcp_addr == TRUE) { + char buffer[1024]; + snprintf(buffer, sizeof(buffer), "%u IN IP4 %s", rtcp_port, rtcp_addr); + sdp_message_a_attribute_add(msg, lineno, osip_strdup("rtcp"), osip_strdup(buffer)); + } else { + sdp_message_a_attribute_add(msg, lineno, osip_strdup("rtcp"), int_2char(rtcp_port)); + } } - add_ice_candidates(msg, lineno, ice_cl, rtp_addr, rtp_port, rtcp_addr, rtcp_port); - add_ice_remote_candidates(msg, lineno, ice_cl); + } + if (desc->ice_mismatch == TRUE) { + sdp_message_a_attribute_add(msg, lineno, osip_strdup("ice-mismatch"), NULL); + } else { + if (desc->ice_pwd[0] != '\0') sdp_message_a_attribute_add(msg, lineno, osip_strdup("ice-pwd"), osip_strdup(desc->ice_pwd)); + if (desc->ice_ufrag[0] != '\0') sdp_message_a_attribute_add(msg, lineno, osip_strdup("ice-ufrag"), osip_strdup(desc->ice_ufrag)); + add_ice_candidates(msg, lineno, desc); + add_ice_remote_candidates(msg, lineno, desc); } } -sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc, const IceSession *ice_session){ - IceCheckList *ice_cl = NULL; +sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc){ int i; - sdp_message_t *msg=create_generic_sdp(desc, ice_session); + sdp_message_t *msg=create_generic_sdp(desc); for(i=0;instreams;++i){ - if (ice_session != NULL) ice_cl = ice_session_check_list(ice_session, i); - else ice_cl = NULL; - add_line(msg,i,&desc->streams[i], ice_cl); + add_line(msg,i,&desc->streams[i]); } return msg; } @@ -474,15 +428,12 @@ static int payload_type_fill_from_rtpmap(PayloadType *pt, const char *rtpmap){ return 0; } -int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceSession **ice_session){ +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 *ice_ufrag, *ice_pwd, *ice_remote_candidates=NULL; sdp_bandwidth_t *sbw=NULL; sdp_attribute_t *attr; - int media_attribute_nb; - bool_t ice_session_just_created = FALSE; - bool_t ice_lite = FALSE; + int nb_ice_candidates; rtp_addr=sdp_message_c_addr_get (msg, -1, 0); if (rtp_addr) @@ -491,10 +442,22 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceS if (strcasecmp(sbw->b_bwtype,"AS")==0) desc->bandwidth=atoi(sbw->b_bandwidth); } + /* Get ICE remote ufrag and remote pwd, and ice_lite flag */ + for (i = 0; (i < SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES) && ((attr = sdp_message_attribute_get(msg, -1, i)) != NULL); i++) { + if ((keywordcmp("ice-ufrag", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { + strncpy(desc->ice_ufrag, attr->a_att_value, sizeof(desc->ice_ufrag)); + } else if ((keywordcmp("ice-pwd", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { + strncpy(desc->ice_pwd, attr->a_att_value, sizeof(desc->ice_pwd)); + } else if (keywordcmp("ice-lite", attr->a_att_field) == 0) { + desc->ice_lite = TRUE; + } + } + /* for each m= line */ for (i=0; !sdp_message_endof_media (msg, i) && istreams[i]; + nb_ice_candidates = 0; memset(stream,0,sizeof(*stream)); mtype = sdp_message_m_media_get(msg, i); @@ -527,7 +490,6 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceS if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth); } stream->dir=_sdp_message_get_mline_dir(msg,i); - media_attribute_nb = 0; /* for each payload type */ for (j=0;((number=sdp_message_m_payload_get (msg, i,j)) != NULL); j++){ const char *rtpmap,*fmtp; @@ -536,11 +498,9 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceS payload_type_set_number(pt,ptn); /* get the rtpmap associated to this codec, if any */ rtpmap=sdp_message_a_attr_value_get_with_pt(msg, i,ptn,"rtpmap"); - if (rtpmap != NULL) media_attribute_nb++; if (payload_type_fill_from_rtpmap(pt,rtpmap)==0){ /* get the fmtp, if any */ fmtp=sdp_message_a_attr_value_get_with_pt(msg, i, ptn,"fmtp"); - if (fmtp != NULL) media_attribute_nb++; payload_type_set_send_fmtp(pt,fmtp); stream->payloads=ms_list_append(stream->payloads,pt); ms_message("Found payload %s/%i fmtp=%s",pt->mime_type,pt->clock_rate, @@ -608,121 +568,37 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceS } /* Get ICE candidate attributes if any */ - ice_ufrag = ice_pwd = NULL; - for (j = 0; (j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES) && ((attr = sdp_message_attribute_get(msg, i, media_attribute_nb + j)) != NULL); j++) { + for (j = 0; (attr = sdp_message_attribute_get(msg, i, j)) != NULL; j++) { if ((keywordcmp("candidate", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - char ip[64]; - char foundation[32]; - char type[6]; - unsigned int priority; - unsigned int componentID; - unsigned int port; - int nb; - - /* Allocate the ICE session if it has not been done yet. */ - if (*ice_session == NULL) { - *ice_session = ice_session_new(); - ice_session_just_created = TRUE; - } - /* Allocate the ICE check list if it has not been done yet. */ - if (ice_session_check_list(*ice_session, i) == NULL) { - ice_session_add_check_list(*ice_session, ice_check_list_new()); - } - nb = sscanf(attr->a_att_value, "%s %u UDP %u %s %u typ %s", - foundation, &componentID, &priority, ip, &port, type); - if (nb == 6) { - char *default_ip = desc->addr; - unsigned int default_port = stream->rtp_port; - bool_t is_default_candidate = FALSE; - if (componentID == 1) { - if ((stream->rtp_addr == NULL) || (stream->rtp_addr[0] == '\0')) default_ip = desc->addr; - else default_ip = stream->rtp_addr; - default_port = stream->rtp_port; - } else if (componentID == 2) { - if ((stream->rtcp_addr == NULL) || (stream->rtcp_addr[0] == '\0')) default_ip = desc->addr; - else default_ip = stream->rtcp_addr; - default_port = stream->rtcp_port; - } - if ((port == default_port) && (strlen(ip) == strlen(default_ip)) && (strcmp(ip, default_ip) == 0)) is_default_candidate = TRUE; - ice_add_remote_candidate(ice_session_check_list(*ice_session, i), type, ip, port, componentID, priority, foundation, is_default_candidate); - } + SalIceCandidate *candidate = &stream->ice_candidates[nb_ice_candidates]; + int nb = sscanf(attr->a_att_value, "%s %u UDP %u %s %d typ %s raddr %s rport %d", + candidate->foundation, &candidate->componentID, &candidate->priority, candidate->addr, &candidate->port, + candidate->type, candidate->raddr, &candidate->rport); + if ((nb == 6) || (nb == 8)) nb_ice_candidates++; + else memset(candidate, 0, sizeof(*candidate)); } else if ((keywordcmp("remote-candidates", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - ice_remote_candidates = attr->a_att_value; - } else if ((keywordcmp("ice-ufrag", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - ice_ufrag = attr->a_att_value; - } else if ((keywordcmp("ice-pwd", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - ice_pwd = attr->a_att_value; - } else if (keywordcmp("ice-mismatch", attr->a_att_field) == 0) { - ice_check_list_set_state(ice_session_check_list(*ice_session, i), ICL_Failed); - } - } - if ((*ice_session != NULL) && ice_session_check_list(*ice_session, i)) { - if (ice_remote_candidates != NULL) { - char ip[64]; - unsigned int port; + SalIceRemoteCandidate candidate; unsigned int componentID; int offset; - - while (3 == sscanf(ice_remote_candidates, "%u %s %u%n", &componentID, ip, &port, &offset)) { - if (componentID == 1) { - if ((stream->rtp_addr == NULL) || (stream->rtp_addr[0] == '\0')) rtp_addr = desc->addr; - else rtp_addr = stream->rtp_addr; - ice_add_losing_pair(ice_session_check_list(*ice_session, i), componentID, ip, port, rtp_addr, stream->rtp_port); - } else if (componentID == 2) { - if ((stream->rtcp_addr == NULL) || (stream->rtcp_addr[0] == '\0')) rtp_addr = desc->addr; - else rtp_addr = stream->rtcp_addr; - ice_add_losing_pair(ice_session_check_list(*ice_session, i), componentID, ip, port, rtp_addr, stream->rtcp_port); + char *ptr = attr->a_att_value; + while (3 == sscanf(ptr, "%u %s %u%n", &componentID, candidate.addr, &candidate.port, &offset)) { + if ((componentID > 0) && (componentID <= SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES)) { + SalIceRemoteCandidate *remote_candidate = &stream->ice_remote_candidates[componentID - 1]; + strncpy(remote_candidate->addr, candidate.addr, sizeof(remote_candidate->addr)); + remote_candidate->port = candidate.port; } - ice_remote_candidates += offset; - if (ice_remote_candidates[offset] == ' ') ice_remote_candidates += 1; + ptr += offset; + if (ptr[offset] == ' ') ptr += 1; } + } else if ((keywordcmp("ice-ufrag", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { + strncpy(stream->ice_ufrag, attr->a_att_value, sizeof(stream->ice_ufrag)); + } else if ((keywordcmp("ice-pwd", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { + strncpy(stream->ice_pwd, attr->a_att_value, sizeof(stream->ice_pwd)); + } else if (keywordcmp("ice-mismatch", attr->a_att_field) == 0) { + stream->ice_mismatch = TRUE; } - if ((ice_ufrag != NULL) && (ice_pwd != NULL)) { - ice_check_list_set_remote_credentials(ice_session_check_list(*ice_session, i), ice_ufrag, ice_pwd); - } - if (stream->rtp_port == 0) { - /* This stream has been deactivated by the peer, delete the check list. */ - ice_session_remove_check_list(*ice_session, ice_session_check_list(*ice_session, i)); - } - ice_dump_candidates(ice_session_check_list(*ice_session, i)); } } desc->nstreams=i; - - /* Get ICE remote ufrag and remote pwd */ - ice_ufrag = ice_pwd = NULL; - for (i = 0; (i < SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES) && ((attr = sdp_message_attribute_get(msg, -1, i)) != NULL); i++) { - if ((keywordcmp("ice-ufrag", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - ice_ufrag = attr->a_att_value; - } else if ((keywordcmp("ice-pwd", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) { - ice_pwd = attr->a_att_value; - } else if (keywordcmp("ice-lite", attr->a_att_field) == 0) { - ice_lite = TRUE; - } - } - if (*ice_session != NULL) { - int nb_check_lists; - if (ice_session_just_created == TRUE) { - if (ice_lite == TRUE) { - ice_session_set_role(*ice_session, IR_Controlling); - } else { - ice_session_set_role(*ice_session, IR_Controlled); - } - ice_session_check_mismatch(*ice_session); - } - while ((nb_check_lists = ice_session_nb_check_lists(*ice_session)) > desc->nstreams) { - ice_session_remove_check_list(*ice_session, ice_session_check_list(*ice_session, nb_check_lists - 1)); - } - if ((ice_ufrag != NULL) && (ice_pwd != NULL)) { - ice_session_set_remote_credentials(*ice_session, ice_ufrag, ice_pwd); - ice_dump_session(*ice_session); - } - if (((ice_session_just_created == FALSE) && ((ice_ufrag == NULL) || (ice_pwd == NULL))) - || (ice_session_state(*ice_session) == IS_Failed)) { - /* We started with ICE activated but the peer apparently do not support ICE, so stop using it. */ - ice_session_destroy(*ice_session); - *ice_session = NULL; - } - } return 0; }