]> sjero.net Git - linphone/commitdiff
fix memory leaks, debug SDP nego
authorSimon Morlat <simon.morlat@linphone.org>
Fri, 12 Feb 2010 09:48:11 +0000 (10:48 +0100)
committerSimon Morlat <simon.morlat@linphone.org>
Fri, 12 Feb 2010 09:48:11 +0000 (10:48 +0100)
coreapi/callbacks.c
coreapi/linphonecore.c
coreapi/offeranswer.c
coreapi/private.h
coreapi/sal.c
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2_sdp.c
mediastreamer2

index 5b5bcad86830c7e685b1b795fc5cb63124e28ddb..f6c5f034acbde14afe3766bdbea05e73d8c4921b 100644 (file)
@@ -77,6 +77,8 @@ static void call_received(SalOp *h){
        lc->call=call;
        sal_call_set_local_media_description(h,call->localdesc);
        call->resultdesc=sal_call_get_final_media_description(h);
+       if (call->resultdesc)
+               sal_media_description_ref(call->resultdesc);
        if (call->resultdesc && sal_media_description_empty(call->resultdesc)){
                sal_call_decline(h,SalReasonMedia,NULL);
                linphone_call_destroy(call);
@@ -101,7 +103,7 @@ static void call_received(SalOp *h){
        }
        linphone_call_set_state(call,LCStateRinging);
        sal_call_notify_ringing(h);
-
+       linphone_core_init_media_streams(lc,lc->call);
        if (lc->vtable.inv_recv) lc->vtable.inv_recv(lc,tmp);
        ms_free(barmesg);
        ms_free(tmp);
@@ -140,6 +142,7 @@ static void call_ringing(SalOp *h){
                }
                ms_message("Doing early media...");
                linphone_core_start_media_streams(lc,call);
+               call->media_pending=TRUE;
        }
        call->state=LCStateRinging;
 }
@@ -166,6 +169,10 @@ static void call_accepted(SalOp *op){
        if (call->resultdesc)
                sal_media_description_unref(call->resultdesc);
        call->resultdesc=sal_call_get_final_media_description(op);
+       if (call->resultdesc){
+               sal_media_description_ref(call->resultdesc);
+               call->media_pending=FALSE;
+       }
        if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
                gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
                linphone_connect_incoming(lc,call);
@@ -187,21 +194,26 @@ static void call_ack(SalOp *op){
                ms_warning("call_ack: ignoring.");
                return;
        }
-       if (lc->audiostream->ticker!=NULL){
-               /*case where we accepted early media */
-               linphone_core_stop_media_streams(lc,call);
-               linphone_core_init_media_streams(lc,call);
-       }
-       if (call->resultdesc)
-               sal_media_description_unref(call->resultdesc);
-       call->resultdesc=sal_call_get_final_media_description(op);
-       if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
-               gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
-               linphone_connect_incoming(lc,call);
-       }else{
-               /*send a bye*/
-               ms_error("Incompatible SDP response received in ACK, need to abort the call");
-               linphone_core_terminate_call(lc,NULL);
+       if (call->media_pending){
+               if (lc->audiostream->ticker!=NULL){
+                       /*case where we accepted early media */
+                       linphone_core_stop_media_streams(lc,call);
+                       linphone_core_init_media_streams(lc,call);
+               }
+               if (call->resultdesc)
+                       sal_media_description_unref(call->resultdesc);
+               call->resultdesc=sal_call_get_final_media_description(op);
+               if (call->resultdesc)
+                       sal_media_description_ref(call->resultdesc);
+               if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
+                       gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
+                       linphone_connect_incoming(lc,call);
+               }else{
+                       /*send a bye*/
+                       ms_error("Incompatible SDP response received in ACK, need to abort the call");
+                       linphone_core_terminate_call(lc,NULL);
+               }
+               call->media_pending=FALSE;
        }
 }
 
index 9dd4cd9cec48edcbbf53f0273ebd8e99c29916d7..6ccac20b50ab535f7765a89f4f539e7e2f976064 100644 (file)
@@ -137,7 +137,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
        LinphoneCall *call=ms_new0(LinphoneCall,1);
        call->dir=LinphoneCallOutgoing;
        call->op=sal_op_new(lc->sal);
-       sal_op_set_user_pointer(call->op,lc->call);
+       sal_op_set_user_pointer(call->op,call);
        call->core=lc;
        linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
        call->localdesc=create_local_media_description (lc,call->localip,
@@ -693,6 +693,37 @@ static bool_t get_codec(LpConfig *config, char* type, int index, PayloadType **r
        return TRUE;
 }
 
+static const char *codec_pref_order[]={
+       "speex",
+       "gsm",
+       "pcmu",
+       "pcma",
+       "H264",
+       "MP4V-ES",
+       "theora",
+       "H263-1998",
+       "H263",
+       NULL,
+};
+
+static int find_codec_rank(const char *mime){
+       int i;
+       for(i=0;codec_pref_order[i]!=NULL;++i){
+               if (strcasecmp(codec_pref_order[i],mime)==0)
+                       break;
+       }
+       return i;
+}
+
+static int codec_compare(const PayloadType *a, const PayloadType *b){
+       int ra,rb;
+       ra=find_codec_rank(a->mime_type);
+       rb=find_codec_rank(b->mime_type);
+       if (ra==rb) return 0;
+       if (ra>rb) return 1;
+       if (ra<rb) return -1;
+}
+
 static MSList *add_missing_codecs(SalStreamType mtype, MSList *l){
        int i;
        for(i=0;i<127;++i){
@@ -709,11 +740,7 @@ static MSList *add_missing_codecs(SalStreamType mtype, MSList *l){
                                        payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED);
                                        ms_message("Adding new codec %s/%i with fmtp %s",
                                            pt->mime_type,pt->clock_rate,pt->recv_fmtp ? pt->recv_fmtp : "");
-                                       if (strcasecmp(pt->mime_type,"speex")==0 ||
-                                           strcasecmp(pt->mime_type,"MP4V-ES")==0 ||
-                                           strcasecmp(pt->mime_type,"H264")==0)
-                                               l=ms_list_prepend(l,pt);
-                                       else l=ms_list_append(l,pt);
+                                       l=ms_list_insert_sorted(l,pt,(int (*)(const void *, const void *))codec_compare);
                                }
                        }
                }
@@ -1733,7 +1760,7 @@ int linphone_core_invite(LinphoneCore *lc, const char *url)
        int err=0;
        char *route=NULL;
        const char *from=NULL;
-       const char *contact=NULL;
+       char *contact=NULL;
        LinphoneProxyConfig *proxy=NULL;
        LinphoneAddress *parsed_url2=NULL;
        LinphoneAddress *real_parsed_url=NULL;
@@ -1775,13 +1802,16 @@ int linphone_core_invite(LinphoneCore *lc, const char *url)
        except when the user choosed to override the ipaddress */
        if (linphone_core_get_firewall_policy(lc)!=LINPHONE_POLICY_USE_NAT_ADDRESS)
                contact=get_fixed_contact(lc,call->localip,dest_proxy);
-       if (contact)
+       if (contact){
                sal_op_set_contact(call->op, contact);
+               ms_free(contact);
+       }
 
        lc->call=call;
 
        linphone_core_init_media_streams(lc,lc->call);
        if (!lc->sip_conf.sdp_200_ack){ 
+               call->media_pending=TRUE;
                sal_call_set_local_media_description(call->op,call->localdesc);
        }
        err=sal_call(call->op,from,real_url);
@@ -1798,10 +1828,8 @@ int linphone_core_invite(LinphoneCore *lc, const char *url)
                lc->call=NULL;
        }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, url);
 
-       goto end;
-       end:
-               if (real_url!=NULL) ms_free(real_url);
-               if (route!=NULL) ms_free(route);
+       if (real_url!=NULL) ms_free(real_url);
+       if (route!=NULL) ms_free(route);
        return (err<0) ? -1 : 0;
 }
 
@@ -1947,9 +1975,9 @@ static void post_configure_audio_streams(LinphoneCore *lc){
        }
 }
 
-static RtpProfile *make_profile(LinphoneCore *lc, SalStreamDescription *desc, int *used_pt){
+static RtpProfile *make_profile(LinphoneCore *lc, const SalStreamDescription *desc, int *used_pt){
        int bw;
-       MSList *elem;
+       const MSList *elem;
        RtpProfile *prof=rtp_profile_new("Call profile");
        bool_t first=TRUE;
        if (desc->type==SalAudio){
@@ -1988,7 +2016,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
 
        cname=linphone_address_as_string_uri_only(me);
        {
-               SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+               const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
                                                        SalProtoRtpAvp,SalAudio);
                if (stream){
                        call->audio_profile=make_profile(lc,stream,&used_pt);
@@ -2032,7 +2060,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
        }
 #ifdef VIDEO_ENABLED
        {
-               SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+               const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
                                                        SalProtoRtpAvp,SalVideo);
                /* shutdown preview */
                if (lc->previewstream!=NULL) {
@@ -2091,10 +2119,12 @@ void linphone_core_stop_media_streams(LinphoneCore *lc, LinphoneCall *call){
        }
 #endif
        if (call->audio_profile){
+               rtp_profile_clear_all(call->audio_profile);
                rtp_profile_destroy(call->audio_profile);
                call->audio_profile=NULL;
        }
        if (call->video_profile){
+               rtp_profile_clear_all(call->video_profile);
                rtp_profile_destroy(call->video_profile);
                call->video_profile=NULL;
        }
@@ -2150,7 +2180,7 @@ int linphone_core_accept_call(LinphoneCore *lc, const char *url)
        if (call->resultdesc){
                sal_media_description_ref(call->resultdesc);
                linphone_core_start_media_streams(lc, call);
-       }
+       }else call->media_pending=TRUE;
        ms_message("call answered.");
        return 0;
 }
@@ -3160,6 +3190,10 @@ void sip_config_uninit(LinphoneCore *lc)
                }
        }
 
+       ms_list_for_each(config->proxies,(void (*)(void*)) linphone_proxy_config_destroy);
+       ms_list_free(config->proxies);
+       config->proxies=NULL;
+       
        linphone_proxy_config_write_to_config_file(lc->config,NULL,i);  /*mark the end */
 
        for(elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
@@ -3167,6 +3201,9 @@ void sip_config_uninit(LinphoneCore *lc)
                linphone_auth_info_write_config(lc->config,ai,i);
        }
        linphone_auth_info_write_config(lc->config,NULL,i); /* mark the end */
+       ms_list_for_each(lc->auth_info,(void (*)(void*))linphone_auth_info_destroy);
+       ms_list_free(lc->auth_info);
+       lc->auth_info=NULL;
        sal_uninit(lc->sal);
        lc->sal=NULL;
 }
index 3e872c6e19d6de30387c4ccde5422ee261541d71..f4b914381e2ccd337e9708f1ba87bd0aa08a7c3e 100644 (file)
@@ -71,11 +71,9 @@ static MSList *match_payloads(const MSList *local, const MSList *remote){
 }
 
 static bool_t only_telephone_event(const MSList *l){
-       for(;l!=NULL;l=l->next){
-               PayloadType *p=(PayloadType*)l->data;
-               if (strcasecmp(p->mime_type,"telephone-event")!=0){
-                       return FALSE;
-               }
+       PayloadType *p=(PayloadType*)l->data;
+       if (strcasecmp(p->mime_type,"telephone-event")!=0){
+               return FALSE;
        }
        return TRUE;
 }
@@ -83,11 +81,15 @@ static bool_t only_telephone_event(const MSList *l){
 static void initiate_outgoing(const SalStreamDescription *local_offer,
                                        const SalStreamDescription *remote_answer,
                                        SalStreamDescription *result){
-       result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads);
+       if (remote_answer->port!=0)
+               result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads);
        if (result->payloads && !only_telephone_event(result->payloads)){
+               strcpy(result->addr,remote_answer->addr);
                result->port=remote_answer->port;
                result->bandwidth=remote_answer->bandwidth;
                result->ptime=remote_answer->ptime;
+               result->proto=local_offer->proto;
+               result->type=local_offer->type;
        }else{
                result->port=0;
        }
@@ -99,9 +101,12 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
                                        SalStreamDescription *result){
        result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads);
        if (result->payloads && !only_telephone_event(result->payloads)){
+               strcpy(result->addr,local_cap->addr);
                result->port=local_cap->port;
                result->bandwidth=local_cap->bandwidth;
                result->ptime=local_cap->ptime;
+               result->proto=local_cap->proto;
+               result->type=local_cap->type;
        }else{
                result->port=0;
        }
@@ -114,11 +119,19 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
 int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
                                                                        const SalMediaDescription *remote_answer,
                                                        SalMediaDescription *result){
-    int i;
-    for(i=0;i<local_offer->nstreams;++i){
-       initiate_outgoing(&local_offer->streams[i],&remote_answer->streams[i],&result->streams[i]);
+    int i,j;
+       const SalStreamDescription *ls,*rs;
+    for(i=0,j=0;i<local_offer->nstreams;++i){
+               ms_message("Processing for stream %i",i);
+               ls=&local_offer->streams[i];
+               rs=sal_media_description_find_stream(remote_answer,ls->proto,ls->type);
+       if (rs) {
+                       initiate_outgoing(ls,rs,&result->streams[j]);
+                       ++j;
+               }
+               else ms_warning("No matching stream for %i",i);
     }
-       result->nstreams=local_offer->nstreams;
+       result->nstreams=j;
        strcpy(result->addr,remote_answer->addr);
        return 0;
 }
@@ -131,11 +144,19 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
 int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
                                                const SalMediaDescription *remote_offer,
                                        SalMediaDescription *result){
-    int i;
-    for(i=0;i<local_capabilities->nstreams;++i){
-       initiate_incoming(&local_capabilities->streams[i],&remote_offer->streams[i],&result->streams[i]);
+    int i,j;
+       const SalStreamDescription *ls,*rs;
+                                                       
+    for(i=0,j=0;i<remote_offer->nstreams;++i){
+               rs=&remote_offer->streams[i];
+               ms_message("Processing for stream %i",i);
+               ls=sal_media_description_find_stream(local_capabilities,rs->proto,rs->type);
+               if (ls){
+               initiate_incoming(ls,rs,&result->streams[j]);
+                       ++j;
+               }
     }
-       result->nstreams=local_capabilities->nstreams;
+       result->nstreams=j;
        strcpy(result->addr,local_capabilities->addr);
        return 0;
 }
index abea80b8292b642567ff82ee41b1dee387bdf7bd..bcd9144399a68b5219196b0c177bb51f9400fc65 100644 (file)
@@ -75,6 +75,7 @@ typedef struct _LinphoneCall
        time_t start_time; /*time at which the call was initiated*/
        time_t media_start_time; /*time at which it was accepted, media streams established*/
        LCState state;
+       bool_t media_pending;
 } LinphoneCall;
 
 LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to);
index d33124e8a4216316de90acf9af7ad4c11d75dacb..ae432d565d4c8b95f77a0c10dd80e544fb1a2155 100644 (file)
@@ -36,6 +36,7 @@ static void sal_media_description_destroy(SalMediaDescription *md){
        for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
                ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
                ms_list_free(md->streams[i].payloads);
+               md->streams[i].payloads=NULL;
        }
        ms_free(md);
 }
@@ -51,11 +52,11 @@ void sal_media_description_unref(SalMediaDescription *md){
        }
 }
 
-SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
+const SalStreamDescription *sal_media_description_find_stream(const SalMediaDescription *md,
     SalMediaProto proto, SalStreamType type){
        int i;
        for(i=0;i<md->nstreams;++i){
-               SalStreamDescription *ss=&md->streams[i];
+               const SalStreamDescription *ss=&md->streams[i];
                if (ss->proto==proto && ss->type==type) return ss;
        }
        return NULL;
index 5dc91efd756188fe51563410ee5055544f190475..eb8042361b3de18a1265c4976cca548f64efe709 100644 (file)
@@ -114,7 +114,7 @@ SalMediaDescription *sal_media_description_new();
 void sal_media_description_ref(SalMediaDescription *md);
 void sal_media_description_unref(SalMediaDescription *md);
 bool_t sal_media_description_empty(SalMediaDescription *md);
-SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
+const SalStreamDescription *sal_media_description_find_stream(const SalMediaDescription *md,
     SalMediaProto proto, SalStreamType type);
 
 /*this structure must be at the first byte of the SalOp structure defined by implementors*/
index ad8e5c19149e565819fa567b989aae1bd184bb12..d3a6d224b683dd48aa2f45c49445ac6d87bcce3f 100644 (file)
@@ -92,6 +92,7 @@ SalOp * sal_op_new(Sal *sal){
        SalOp *op=ms_new(SalOp,1);
        __sal_op_init(op,sal);
        op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
+       op->result=NULL;
        op->supports_session_timers=FALSE;
        op->sdp_offering=TRUE;
        op->pending_auth=NULL;
@@ -109,11 +110,14 @@ void sal_op_release(SalOp *op){
                sal_remove_register(op->base.root,op->rid);
        }
        if (op->cid!=-1){
+               ms_message("Cleaning cid %i",op->cid);
                eXosip_call_set_reference(op->cid,NULL);
        }
        if (op->pending_auth){
                sal_remove_pending_auth(op->base.root,op);
        }
+       if (op->result)
+               sal_media_description_unref(op->result);
        __sal_op_free(op);
 }
 
@@ -280,6 +284,7 @@ static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *de
 }
 
 static void sdp_process(SalOp *h){
+       ms_message("Doing SDP offer/answer process");
        if (h->result){
                sal_media_description_unref(h->result);
        }
@@ -323,8 +328,10 @@ int sal_call(SalOp *h, const char *from, const char *to){
                ms_error("Could not create call.");
                return -1;
        }
-       if (h->base.contact)
+       if (h->base.contact){
+               osip_list_special_free(&invite->contacts,(void (*)(void*))osip_contact_free);
                osip_message_set_contact(invite,h->base.contact);
+       }
        if (h->base.root->session_expires!=0){
                osip_message_set_header(invite, "Session-expires", "200");
                osip_message_set_supported(invite, "timer");
@@ -472,6 +479,7 @@ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
                eXosip_unlock();
                eXosip_clear_authentication_info();
                eXosip_event_free(h->pending_auth);
+               sal_remove_pending_auth(sal_op_get_sal(h),h);
                h->pending_auth=NULL;
        }
 }
@@ -482,6 +490,7 @@ static void inc_new_call(Sal *sal, eXosip_event_t *ev){
        char *tmp;
        sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
        if (sdp){
+               op->sdp_offering=FALSE;
                op->base.remote_media=sal_media_description_new();
                sdp_to_media_description(sdp,op->base.remote_media);
                sdp_message_free(sdp);
@@ -635,12 +644,14 @@ static void call_terminated(Sal *sal, eXosip_event_t *ev){
 
 static void call_released(Sal *sal, eXosip_event_t *ev){
        SalOp *op;
+       char *from;
        op=(SalOp*)ev->external_reference;
        if (op==NULL){
                return;
        }
-       eXosip_call_set_reference(ev->cid,NULL);
-       /*sal->callbacks.call_terminated(op);*/
+       op->cid=-1;
+       if (op->did==-1) 
+               sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL);
 }
 
 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
@@ -1160,7 +1171,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){
                        }
                        break;
                default:
-                       ms_message("Unhandled exosip event !");
+                       ms_message("Unhandled exosip event ! %i");
                        break;
        }
        return TRUE;
index 1189477d6b282fece036c760f9fe60bb0db92b22..3dfde45d3a4f1a149868ed40ae893cf042eaf352 100644 (file)
@@ -252,6 +252,9 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                addr = sdp_message_c_addr_get (msg, i, 0);
                if (addr != NULL)
                        strncpy(stream->addr,addr,sizeof(stream->addr));
+               if (port)
+                       stream->port=atoi(port);
+               
                stream->ptime=_sdp_message_get_a_ptime(msg,i);
                if (strcasecmp("audio", mtype) == 0){
                        stream->type=SalAudio;
@@ -273,7 +276,11 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                        /* get the fmtp, if any */
                        fmtp=sdp_message_a_attr_value_get_with_pt(msg, i, ptn,"fmtp");
                        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,
+                           pt->send_fmtp ? pt->send_fmtp : "");
                }
        }
+       desc->nstreams=i;
        return 0;
 }
index 8dae09b11ee8a0fe29674944b207b5e06fb0f4ed..ae7dfdcaea6d5fe6d4f44a6247b4ca506799e379 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 8dae09b11ee8a0fe29674944b207b5e06fb0f4ed
+Subproject commit ae7dfdcaea6d5fe6d4f44a6247b4ca506799e379