]> sjero.net Git - linphone/commitdiff
Moved ICE session and check lists respectively from LinphoneCall and SalMediaDescript...
authorGhislain MARY <ghislain.mary@belledonne-communications.com>
Thu, 19 Jul 2012 12:13:37 +0000 (14:13 +0200)
committerGhislain MARY <ghislain.mary@belledonne-communications.com>
Thu, 19 Jul 2012 13:03:27 +0000 (15:03 +0200)
coreapi/linphonecall.c
coreapi/misc.c
coreapi/offeranswer.c
coreapi/private.h
coreapi/sal.c
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h
coreapi/sal_eXosip2_sdp.c

index 28bc348b21f3779f83a089f9fbb24508f1b866f6..5689f8dd3cefc9119570a7342447189abe83afb7 100644 (file)
@@ -201,7 +201,7 @@ 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;
@@ -245,17 +245,10 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
                                md->streams[i].crypto[1].algo = 0;
                        md->streams[i].crypto[2].algo = 0;
                }
-               if ((call->dir == LinphoneCallOutgoing) && (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce)){
-                       md->streams[i].ice_check_list = ice_check_list_new();
-                       ice_session_add_check_list(call->ice_session, md->streams[i].ice_check_list);
-               }
-               if ((call->dir == LinphoneCallIncoming) && (sal_call_get_remote_media_description(call->op)->streams[i].ice_check_list != NULL)) {
-                       md->streams[i].ice_check_list = sal_call_get_remote_media_description(call->op)->streams[i].ice_check_list;
+               if ((call->dir == LinphoneCallOutgoing) && (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (ice_session != NULL)){
+                       ice_session_add_check_list(ice_session, ice_check_list_new());
                }
        }
-       if ((call->dir == LinphoneCallIncoming) && (md->streams[0].ice_check_list != NULL)) {
-               call->ice_session=md->streams[0].ice_check_list->session;
-       }
        
        linphone_address_destroy(addr);
        return md;
@@ -349,8 +342,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) {
-               call->ice_session=ice_session_new();
-               ice_session_set_role(call->ice_session, IR_Controlling);
+               sal_op_set_ice_session(call->op, ice_session_new());
+               ice_session_set_role(sal_op_get_ice_session(call->op), IR_Controlling);
        }
        call->localdesc=create_local_media_description (lc,call);
        call->camera_active=params->has_video;
@@ -555,10 +548,6 @@ static void linphone_call_destroy(LinphoneCall *obj)
                sal_op_release(obj->op);
                obj->op=NULL;
        }
-       if (obj->ice_session!=NULL) {
-               ice_session_destroy(obj->ice_session);
-               obj->ice_session=NULL;
-       }
        if (obj->resultdesc!=NULL) {
                sal_media_description_unref(obj->resultdesc);
                obj->resultdesc=NULL;
@@ -939,6 +928,7 @@ void linphone_call_init_media_streams(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].port,linphone_core_ipv6_enabled(lc));
        if (linphone_core_echo_limiter_enabled(lc)){
@@ -971,10 +961,9 @@ void linphone_call_init_media_streams(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){
-               rtp_session_set_pktinfo(audiostream->session,TRUE);
-               if (call->dir == LinphoneCallOutgoing) audiostream->ice_check_list = call->localdesc->streams[0].ice_check_list;
-               else audiostream->ice_check_list = sal_call_get_remote_media_description(call->op)->streams[0].ice_check_list;
+       if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (ice_session != NULL)){
+               rtp_session_set_pktinfo(audiostream->session, TRUE);
+               audiostream->ice_check_list = ice_session_check_list(ice_session, 0);
                ice_check_list_register_success_cb(audiostream->ice_check_list, audio_stream_set_remote_from_ice, audiostream);
        }
 
@@ -997,10 +986,9 @@ void linphone_call_init_media_streams(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){
-                       rtp_session_set_pktinfo(call->videostream->session,TRUE);
-                       if (call->dir == LinphoneCallOutgoing) call->videostream->ice_check_list = call->localdesc->streams[1].ice_check_list;
-                       else call->videostream->ice_check_list = sal_call_get_remote_media_description(call->op)->streams[1].ice_check_list;
+               if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (ice_session != NULL)){
+                       rtp_session_set_pktinfo(call->videostream->session, TRUE);
+                       call->videostream->ice_check_list = ice_session_check_list(ice_session, 1);
                        ice_check_list_register_success_cb(call->videostream->ice_check_list, video_stream_set_remote_from_ice, call->videostream);
                }
                call->videostream_app_evq = ortp_ev_queue_new();
@@ -1452,6 +1440,7 @@ 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_pair_candidates(sal_op_get_ice_session(call->op));
 
        goto end;
        end:
index 2ef0e04bf6b981f60fe74e4dc952abc45e248711..1dadcb3359115185968afe37f9aa136ae646cb2d 100644 (file)
@@ -576,6 +576,7 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        IceCandidate *video_ice_bases[2];
        IceCheckList *audio_check_list;
        IceCheckList *video_check_list;
+       IceSession *ice_session = sal_op_get_ice_session(call->op);
        struct sockaddr_storage ss;
        socklen_t ss_len;
        struct timeval init, cur;
@@ -583,7 +584,11 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        int loops = 0;
        const char *server = linphone_core_get_stun_server(lc);
 
-       if (server == NULL) return;
+       if ((server == NULL) || (ice_session == NULL)) return;
+       audio_check_list = ice_session_check_list(ice_session, 0);
+       video_check_list = ice_session_check_list(ice_session, 1);
+       if (audio_check_list == NULL) return;
+
        if (lc->sip_conf.ipv6_enabled){
                ms_warning("stun support is not implemented for ipv6");
                return;
@@ -600,8 +605,6 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        video_responses[0] = video_responses[1] = FALSE;
        audio_ice_bases[0] = audio_ice_bases[1] = NULL;
        video_ice_bases[0] = video_ice_bases[1] = NULL;
-       audio_check_list = call->localdesc->streams[0].ice_check_list;
-       video_check_list = call->localdesc->streams[1].ice_check_list;
        audio_socks[0] = create_socket(call->audio_port);
        if (audio_socks[0] == -1) return;
        audio_socks[1] = create_socket(call->audio_port + 1);
@@ -620,7 +623,7 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        }
        audio_ice_bases[0] = ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port, 1, NULL);
        audio_ice_bases[1] = ice_add_local_candidate(audio_check_list, "host", local_addr, call->audio_port + 1, 2, NULL);
-       if (call->params.has_video) {
+       if (call->params.has_video && (video_check_list != NULL)) {
                video_ice_bases[0] = ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port, 1, NULL);
                video_ice_bases[1] = ice_add_local_candidate(video_check_list, "host", local_addr, call->video_port + 1, 2, NULL);
        }
@@ -650,7 +653,7 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
                        ice_add_local_candidate(audio_check_list, "srflx", addr, port, 2, audio_ice_bases[1]);
                        audio_responses[1] = TRUE;
                }
-               if (call->params.has_video) {
+               if (call->params.has_video && (video_check_list != NULL)) {
                        if (recvStunResponse(video_socks[0], addr, &port, &id) > 0) {
                                ice_add_local_candidate(video_check_list, "srflx", addr, port, 1, video_ice_bases[0]);
                                video_responses[0] = TRUE;
@@ -671,13 +674,13 @@ void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
        } while (!((audio_responses[0] == TRUE) && (audio_responses[1] == TRUE)
                && (!call->params.has_video || ((video_responses[0] == TRUE) && (video_responses[1] == TRUE)))));
 
-       ice_session_compute_candidates_foundations(call->ice_session);
-       ice_session_choose_default_candidates(call->ice_session);
+       ice_session_compute_candidates_foundations(ice_session);
+       ice_session_choose_default_candidates(ice_session);
 
        close_socket(audio_socks[0]);
        close_socket(audio_socks[1]);
        ice_dump_candidates(audio_check_list);
-       if (call->params.has_video) {
+       if (call->params.has_video && (video_check_list != NULL)) {
                if (video_socks[0] != -1) close_socket(video_socks[0]);
                if (video_socks[1] != -1) close_socket(video_socks[1]);
                ice_dump_candidates(video_check_list);
index 7b6ce018fb185f24605922423e964725d1ca0202..5a2b4f5275ab90c4f5533cf973acbdfe1d1b6571 100644 (file)
@@ -223,7 +223,6 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
                if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE))
                        result->port = 0;
        }
-       result->ice_check_list = remote_answer->ice_check_list;
 }
 
 
@@ -250,7 +249,6 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
                        result->port = 0; 
                
        }
-       result->ice_check_list = local_cap->ice_check_list;
 }
 
 /**
@@ -311,7 +309,6 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
                        if (rs->type==SalOther){
                                strncpy(result->streams[i].typeother,rs->typeother,sizeof(rs->typeother)-1);
                        }
-                       result->streams[i].ice_check_list = remote_offer->streams[i].ice_check_list;
                }
        }
        result->nstreams=i;
index 2a2cd78161f3ea69c6ab210b3ae7949dff6bf952..241da02236f5fc6d35e4ec1af2f0d5838b25b9a8 100644 (file)
@@ -136,7 +136,6 @@ struct _LinphoneCall
        bool_t was_automatically_paused;
        CallCallbackObj nextVideoFrameDecoded;
        LinphoneCallStats stats[2];
-       IceSession *ice_session;
 };
 
 
index 874c3716d7d1d41dd582ff06ff5c7976b1a400c3..37e56fade4a1f9bf5eeaac97083398b04ad94ada 100644 (file)
@@ -232,6 +232,10 @@ 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;
 }
@@ -260,6 +264,10 @@ 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;
 }
@@ -308,6 +316,8 @@ 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);
 }
 
index 8bd2523fda9266a7d1a7dd1536262179c868b99c..8782226b8ecd20f9859ad41b085cdfd31d5fc338 100644 (file)
@@ -136,7 +136,6 @@ typedef struct SalStreamDescription{
        SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX];
        unsigned int crypto_local_tag;
        int max_rate;
-       IceCheckList *ice_check_list;
 } SalStreamDescription;
 
 #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4
@@ -176,6 +175,7 @@ typedef struct SalOpBase{
        char *remote_ua;
        SalMediaDescription *local_media;
        SalMediaDescription *remote_media;
+       IceSession *ice_session;
        void *user_pointer;
 } SalOpBase;
 
@@ -320,6 +320,7 @@ 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);
@@ -331,6 +332,7 @@ 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);
index 8333f15542a323e5836a54578397e1dd267f2510..62eddddb82e2d72d054ea3340e65d6be83452d4a 100644 (file)
@@ -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){
-       sdp_message_t *msg=media_description_to_sdp(desc);
+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);
        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);
+               h->sdp_answer=media_description_to_sdp(h->result, sal_op_get_ice_session(h));
                /*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);
@@ -598,7 +598,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);
+               set_sdp_from_desc(invite,h->base.local_media,sal_op_get_ice_session(h));
        }else h->sdp_offering=FALSE;
        if (h->replaces){
                osip_message_set_header(invite,"Replaces",h->replaces);
@@ -666,7 +666,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);
+                       set_sdp_from_desc(msg,h->base.local_media,sal_op_get_ice_session(h));
                }else{
                        if (h->sdp_answer==NULL) sdp_process(h);
                        if (h->sdp_answer){
@@ -988,6 +988,7 @@ 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);
@@ -996,7 +997,9 @@ 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();
-               sdp_to_media_description(sdp,op->base.remote_media);
+               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_message_free(sdp);
        }else op->sdp_offering=TRUE;
 
@@ -1032,6 +1035,7 @@ 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 !");
@@ -1051,7 +1055,9 @@ static void handle_reinvite(Sal *sal,  eXosip_event_t *ev){
        if (sdp){
                op->sdp_offering=FALSE;
                op->base.remote_media=sal_media_description_new();
-               sdp_to_media_description(sdp,op->base.remote_media);
+               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_message_free(sdp);
                
        }else {
@@ -1063,6 +1069,7 @@ 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 !");
@@ -1079,7 +1086,9 @@ 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();
-                       sdp_to_media_description(sdp,op->base.remote_media);
+                       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_process(op);
                        sdp_message_free(sdp);
                }
@@ -1139,13 +1148,16 @@ 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();
-               sdp_to_media_description(sdp,op->base.remote_media);
+               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_message_free(sdp);
                if (op->base.local_media) sdp_process(op);
        }
@@ -1157,6 +1169,7 @@ 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.");
@@ -1172,7 +1185,9 @@ 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();
-               sdp_to_media_description(sdp,op->base.remote_media);
+               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_message_free(sdp);
                if (op->base.local_media) sdp_process(op);
        }
@@ -2410,7 +2425,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);
+               set_sdp_from_desc(reinvite,h->base.local_media,sal_op_get_ice_session(h));
        }else h->sdp_offering=FALSE;
        eXosip_lock();
        err = eXosip_call_send_request(h->did, reinvite);
index ccc95d56a76f30d758999e2527a57176c030084d..e3264f74de5fca0d69bc2932441adffea96034fc 100644 (file)
@@ -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);
-int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc);
+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);
 
 struct Sal{
        SalCallbacks callbacks;
index 4faad395fc48d6cd8412fa600950436034f1672c..16e709718ce246f39e89f806ec566cab32732a26 100644 (file)
@@ -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)
+static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc, const IceSession *ice_session)
 {
        sdp_message_t *local;
        int inet6;
@@ -144,8 +144,8 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
                          osip_strdup ("IN"), inet6 ? osip_strdup("IP6") : osip_strdup ("IP4"),
                          osip_strdup (desc->addr));
        sdp_message_s_name_set (local, osip_strdup ("Talk"));
-       if (desc->streams[0].ice_check_list != NULL) {
-               const IceCandidate *candidate = ice_check_list_default_local_candidate(desc->streams[0].ice_check_list);
+       if ((ice_session != NULL) && (ice_session_check_list(ice_session, 0) != NULL)) {
+               const IceCandidate *candidate = ice_check_list_default_local_candidate(ice_session_check_list(ice_session, 0));
                if (candidate != NULL) {
                        addr=candidate->taddr.ip;
                }
@@ -165,11 +165,11 @@ static sdp_message_t *create_generic_sdp(const SalMediaDescription *desc)
        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 (desc->streams[0].ice_check_list != NULL) {
+       if ((ice_session != NULL) && (ice_session_check_list(ice_session, 0) != NULL)) {
                char buffer[512];
-               snprintf(buffer ,sizeof(buffer), "%s", ice_session_local_pwd(desc->streams[0].ice_check_list->session));
+               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(desc->streams[0].ice_check_list->session));
+               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));
        }
 
@@ -212,15 +212,15 @@ static void add_payload(sdp_message_t *msg, int line, const PayloadType *pt, boo
        }
 }
 
-static void add_ice_candidates(sdp_message_t *msg, int lineno, const SalStreamDescription *desc)
+static void add_ice_candidates(sdp_message_t *msg, int lineno, const SalStreamDescription *desc, const IceCheckList *ice_cl)
 {
        char buffer[1024];
        const IceCandidate *candidate;
        int i;
 
-       if (desc->ice_check_list != NULL) {
-               for (i = 0; i < ms_list_size(desc->ice_check_list->local_candidates); i++) {
-                       candidate = ms_list_nth_data(desc->ice_check_list->local_candidates, i);
+       if (ice_cl != NULL) {
+               for (i = 0; i < ms_list_size(ice_cl->local_candidates); i++) {
+                       candidate = ms_list_nth_data(ice_cl->local_candidates, i);
                        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));
                        sdp_message_a_attribute_add(msg, lineno, osip_strdup("candidate"), osip_strdup(buffer));
@@ -229,7 +229,7 @@ static void add_ice_candidates(sdp_message_t *msg, int lineno, const SalStreamDe
 }
 
 
-static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc){
+static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription *desc, const IceCheckList *ice_cl){
        const char *mt=NULL;
        const MSList *elem;
        const char *addr;
@@ -250,8 +250,8 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
        }
        addr=desc->addr;
        port=desc->port;
-       if (desc->ice_check_list != NULL) {
-               const IceCandidate *candidate = ice_check_list_default_local_candidate(desc->ice_check_list);
+       if (ice_cl != NULL) {
+               const IceCandidate *candidate = ice_check_list_default_local_candidate(ice_cl);
                if (candidate != NULL) {
                        addr=candidate->taddr.ip;
                        port=candidate->taddr.port;
@@ -342,15 +342,18 @@ 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);
-       add_ice_candidates(msg, lineno, desc);
+       add_ice_candidates(msg, lineno, desc, ice_cl);
 }
 
 
-sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc){
+sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc, const IceSession *ice_session){
+       IceCheckList *ice_cl = NULL;
        int i;
-       sdp_message_t *msg=create_generic_sdp(desc);
+       sdp_message_t *msg=create_generic_sdp(desc, ice_session);
        for(i=0;i<desc->nstreams;++i){
-               add_line(msg,i,&desc->streams[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);
        }
        return msg;
 }
@@ -386,11 +389,10 @@ 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){
+int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc, IceSession **ice_session){
        int i,j;
        const char *mtype,*proto,*port,*addr,*number;
        const char *ice_ufrag, *ice_pwd;
-       IceSession *ice_session = NULL;
        sdp_bandwidth_t *sbw=NULL;
        sdp_attribute_t *attr;
        int media_attribute_nb;
@@ -515,16 +517,15 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                                int nb;
 
                                /* Allocate the ICE session if it has not been done yet. */
-                               if (ice_session == NULL) ice_session = ice_session_new();
+                               if (*ice_session == NULL) *ice_session = ice_session_new();
                                /* Allocate the ICE check list if it has not been done yet. */
-                               if (desc->streams[i].ice_check_list == NULL) {
-                                       desc->streams[i].ice_check_list = ice_check_list_new();
-                                       ice_session_add_check_list(ice_session, desc->streams[i].ice_check_list);
+                               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) {
-                                       ice_add_remote_candidate(desc->streams[i].ice_check_list, type, ip, port, componentID, priority, foundation);
+                                       ice_add_remote_candidate(ice_session_check_list(*ice_session, i), type, ip, port, componentID, priority, foundation);
                                }
                        } else if ((keywordcmp("ice-ufrag", attr->a_att_field) == 0) && (attr->a_att_value != NULL)) {
                                ice_ufrag = attr->a_att_value;
@@ -532,10 +533,12 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                                ice_pwd = attr->a_att_value;
                        }
                }
-               if ((ice_ufrag != NULL) && (ice_pwd != NULL)) {
-                       ice_check_list_set_remote_credentials(desc->streams[i].ice_check_list, ice_ufrag, ice_pwd);
+               if ((*ice_session != NULL) && ice_session_check_list(*ice_session, i)) {
+                       if ((ice_ufrag != NULL) && (ice_pwd != NULL)) {
+                               ice_check_list_set_remote_credentials(ice_session_check_list(*ice_session, i), ice_ufrag, ice_pwd);
+                       }
+                       ice_dump_candidates(ice_session_check_list(*ice_session, i));
                }
-               if (desc->streams[i].ice_check_list) ice_dump_candidates(desc->streams[i].ice_check_list);
        }
        /* Get ICE remote ufrag and remote pwd */
        ice_ufrag = ice_pwd = NULL;
@@ -548,15 +551,15 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                        ice_lite = TRUE;
                }
        }
-       if (ice_session != NULL) {
+       if (*ice_session != NULL) {
                if (ice_lite == TRUE) {
-                       ice_session_set_role(ice_session, IR_Controlling);
+                       ice_session_set_role(*ice_session, IR_Controlling);
                } else {
-                       ice_session_set_role(ice_session, IR_Controlled);
+                       ice_session_set_role(*ice_session, IR_Controlled);
                }
                if ((ice_ufrag != NULL) && (ice_pwd != NULL)) {
-                       ice_session_set_remote_credentials(ice_session, ice_ufrag, ice_pwd);
-                       ice_dump_session(ice_session);
+                       ice_session_set_remote_credentials(*ice_session, ice_ufrag, ice_pwd);
+                       ice_dump_session(*ice_session);
                }
        }
        desc->nstreams=i;