Commit f6537cb2 authored by Simon Morlat's avatar Simon Morlat
Browse files

fix release of call objects

parent be086cd0
......@@ -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);
}
}
......
......@@ -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;
}
/**
* @}
**/
......@@ -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;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment