]> sjero.net Git - linphone/commitdiff
fix release of call objects
authorSimon Morlat <simon.morlat@linphone.org>
Wed, 2 Jun 2010 12:18:07 +0000 (14:18 +0200)
committerSimon Morlat <simon.morlat@linphone.org>
Wed, 2 Jun 2010 12:18:07 +0000 (14:18 +0200)
coreapi/callbacks.c
coreapi/linphonecall.c
coreapi/linphonecore.c

index 4b53ffdad3d2078097bfca75f97ac51a8a11ef01..31b5e723a900f81ab188bc3a56c4952e46ed3327 100644 (file)
@@ -82,17 +82,11 @@ static void call_received(SalOp *h){
        to=sal_op_get_to(h);
        
        call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),h);
-       if(linphone_core_add_call(lc,call)!= 0)
-       {
-               ms_warning("we cannot have more calls\n");
-               sal_call_decline(h,SalReasonMedia,NULL);
-               linphone_call_unref(call);
-               return;
-       }
+       
        if(linphone_core_get_current_call(lc)!=NULL) //we are already in call just inform that an incoming call is going on
        {
                char temp[256];
-               snprintf(temp,sizeof(temp),"A new incoming call from %s during call",from);
+               snprintf(temp,sizeof(temp)-1,"A new incoming call from %s during call",from);
                lc->vtable.display_status(lc,temp);
        }
        sal_call_set_local_media_description(h,call->localdesc);
@@ -104,6 +98,8 @@ static void call_received(SalOp *h){
                linphone_call_unref(call);
                return;
        }
+       /* the call is acceptable so we can now add it to our list */
+       linphone_core_add_call(lc,call);
        
        from_parsed=linphone_address_new(sal_op_get_from(h));
        linphone_address_clean(from_parsed);
@@ -330,18 +326,19 @@ static void call_terminated(SalOp *op, const char *from){
                lc->vtable.show(lc);
        if (lc->vtable.display_status!=NULL)
                lc->vtable.display_status(lc,_("Call terminated."));
-       linphone_call_set_terminated(call);
+       call->state=LinphoneCallTerminated;
        gstate_new_state(lc, GSTATE_CALL_END, NULL);
        if (lc->vtable.bye_recv!=NULL){
                LinphoneAddress *addr=linphone_address_new(from);
                char *tmp;
                linphone_address_clean(addr);
                tmp=linphone_address_as_string(addr);
-               lc->vtable.bye_recv(lc,call);
+               if (lc->vtable.bye_recv!=NULL)
+                       lc->vtable.bye_recv(lc,call);
                ms_free(tmp);
                linphone_address_destroy(addr);
        }
-       linphone_call_unref(call);
+       linphone_call_set_terminated(call);
 }
 
 static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){
@@ -413,10 +410,9 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
        if(call == linphone_core_get_current_call(lc))
                linphone_core_stop_media_streams(lc,call);
        if (call!=NULL) {
-               linphone_call_set_terminated(call);
-               linphone_call_unref(call);//TODO not an unref here ???//AUREL
                if (sr!=SalReasonDeclined) gstate_new_state(lc, GSTATE_CALL_ERROR, msg);
                else gstate_new_state(lc, GSTATE_CALL_END, NULL);
+               linphone_call_set_terminated(call);
        }
 }
 
index 26ece225bda8dc4b2be5464b1028c02971b917bf..ac165a6294feaa87745162c95da322cb5e2bac14 100644 (file)
@@ -151,20 +151,45 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
        return call;
 }
 
+/* this function is called internally to get rid of a call.
+ It performs the following tasks:
+ - remove the call from the internal list of calls
+ - unref the LinphoneCall object
+ - update the call logs accordingly
+*/
+
 void linphone_call_set_terminated(LinphoneCall *call){
        LinphoneCallStatus status=LinphoneCallAborted;
+       LinphoneCore *lc=call->core;
+
+       if (ms_list_size(lc->calls)==0)
+               linphone_core_notify_all_friends(lc,lc->prev_mode);
+       
+       linphone_core_update_allocated_audio_bandwidth(lc);
        if (call->state==LinphoneCallAVRunning){
                status=LinphoneCallSuccess;
+               
        }
        linphone_call_log_completed(call->log,call, status);
        call->state=LinphoneCallTerminated;
+       if (linphone_core_del_call(lc,call) != 0){
+               ms_error("could not remove the call from the list !!!");
+       }
+       if (call == linphone_core_get_current_call(lc)){
+               ms_message("destroying the current call\n");
+               linphone_core_unset_the_current_call(lc);
+       }
+       if (call->op!=NULL) {
+               /* so that we cannot have anymore upcalls for SAL
+                concerning this call*/
+               sal_op_release(call->op);
+               call->op=NULL;
+       }
+       linphone_call_unref(call);
 }
 
 static void linphone_call_destroy(LinphoneCall *obj)
 {
-       linphone_core_notify_all_friends(obj->core,obj->core->prev_mode);
-       
-       linphone_core_update_allocated_audio_bandwidth(obj->core);
        if (obj->op!=NULL) {
                sal_op_release(obj->op);
                obj->op=NULL;
@@ -180,40 +205,62 @@ static void linphone_call_destroy(LinphoneCall *obj)
        if (obj->ping_op) {
                sal_op_release(obj->ping_op);
        }
-       if(linphone_core_del_call(obj->core,obj) != 0)
-       {
-               ms_error("could not remove the call from the list !!!");
-       }
-       if(obj == linphone_core_get_current_call(obj->core))
-       {
-               ms_message("destroying the current call\n");
-               linphone_core_unset_the_current_call(obj->core);
-       }
        ms_free(obj);
 }
 
+/**
+ * @addtogroup calls
+ * @{
+**/
+
+/**
+ * Increments the call 's reference count.
+ * An application that wishes to retain a pointer to call object
+ * must use this function to unsure the pointer remains
+ * valid. Once the application no more needs this pointer,
+ * it must call linphone_call_unref().
+**/
 void linphone_call_ref(LinphoneCall *obj){
        obj->refcnt++;
 }
 
+/**
+ * Decrements the call object reference count.
+ * See linphone_call_ref().
+**/
 void linphone_call_unref(LinphoneCall *obj){
        obj->refcnt--;
        if (obj->refcnt==0)
                linphone_call_destroy(obj);
 }
 
+/**
+ * Returns true if the call is paused.
+**/
 bool_t linphone_call_paused(LinphoneCall *call){
        return call->state==LinphoneCallPaused;
 }
 
+/**
+ * Returns the remote address associated to this call
+ *
+**/
 const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call){
        return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to;
 }
 
+/**
+ * Returns the remote address associated to this call as a string.
+ *
+ * The result string must be freed by user using ms_free().
+**/
 char *linphone_call_get_remote_address_as_string(const LinphoneCall *call){
        return linphone_address_as_string(linphone_call_get_remote_address(call));
 }
 
+/**
+ * Retrieves the call's current state.
+**/
 LinphoneCallState linphone_call_get_state(const LinphoneCall *call){
        return call->state;
 }
@@ -241,3 +288,8 @@ void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer)
 {
        call->user_pointer = user_pointer;
 }
+
+/**
+ * @}
+**/
+
index ac10f2453806121730005d0161540f52e6c3e1be..a58061421a889cf0bd6fbda771bcc32d060b4051 100644 (file)
@@ -1523,7 +1523,7 @@ static void linphone_core_do_plugin_tasks(LinphoneCore *lc){
  * serialized with a mutex.
 **/
 void linphone_core_iterate(LinphoneCore *lc){
-       MSList *the_call;
+       MSList *calls;
        LinphoneCall *call;
        int disconnect_timeout = linphone_core_get_nortp_timeout(lc);
        time_t curtime=time(NULL);
@@ -1550,10 +1550,13 @@ void linphone_core_iterate(LinphoneCore *lc){
        proxy_update(lc);
 
        //we have to iterate for each call
-       the_call = lc->calls;
-       while(the_call != NULL)
-       {
-               call = (LinphoneCall *)the_call->data;
+       calls= lc->calls;
+       while(calls!= NULL){
+               call = (LinphoneCall *)calls->data;
+                /* get immediately a reference to next one in case the one
+                we are going to examine is destroy and removed during
+                linphone_core_start_invite() */
+               calls=calls->next;
                if (call->state==LinphoneCallPreEstablishing && (curtime-call->start_time>=2)){
                                /*start the call even if the OPTIONS reply did not arrive*/
                                linphone_core_start_invite(lc,call,NULL);
@@ -1566,10 +1569,7 @@ void linphone_core_iterate(LinphoneCore *lc){
                                        linphone_core_terminate_call(lc,call);
                                }
                        }
-
-               the_call = the_call->next;
-       }//end while
-       //and consider the current call
+       }
        call = linphone_core_get_current_call(lc);
        if(call)
        {
@@ -1840,7 +1840,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
                        lc->vtable.display_status(lc,_("could not call"));
                if(call == linphone_core_get_current_call(lc))
                        linphone_core_stop_media_streams(lc,call);
-               linphone_call_unref(call);
+               linphone_call_set_terminated (call);
        }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, real_url);
        ms_free(real_url);
        ms_free(from);
@@ -2377,7 +2377,6 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
                lc->vtable.display_status(lc,_("Call ended") );
        gstate_new_state(lc, GSTATE_CALL_END, NULL);
        linphone_call_set_terminated(call);
-       linphone_call_unref(call);
        return 0;
 }
 
@@ -3788,6 +3787,7 @@ bool_t linphone_core_can_we_add_call(LinphoneCore *lc)
 {
        if(linphone_core_get_calls_nb(lc) < NB_MAX_CALLS)
                return TRUE;
+       ms_error("Maximum amount of simultaneous calls reached !");
        return FALSE;
 }
 
@@ -3828,7 +3828,7 @@ int linphone_core_add_call( LinphoneCore *lc, LinphoneCall *call)
        if(linphone_core_can_we_add_call(lc))
        {
                MSList *the_calls = lc->calls;
-               the_calls = ms_list_append(the_calls,(void *)call);
+               the_calls = ms_list_append(the_calls,call);
                lc->calls = the_calls;
                return 0;
        }