- creation of another outgoing call while already in call
- blind call transfer
- attended call transfer
+ **CAUTION**: LinphoneCoreVTable has changed: pay attention to this when upgrading an old application to a newer liblinphone.
* improve bandwidth management (one b=AS line is used for audio+video)
- * improvements in the echo limiter
+ * improvements in the echo limiter performance
+ * implement a echo calibration feature (see linphone_core_start_echo_calibration()).
* stun support bugfixes
* possibility to use two video windows, one for local preview, one for remote video (linphonec only)
* optimize by not re-creating streams when SDP is unchanged during a reinvite
endif
-sipomatic_SOURCES=\
- sipomatic.c sipomatic.h
-sipomatic_CFLAGS= $(COMMON_CFLAGS) $(CONSOLE_FLAGS)
-
-sipomatic_LDADD= $(INTLLIBS) \
- $(top_builddir)/coreapi/liblinphone.la \
- $(MEDIASTREAMER_LIBS) \
- $(ORTP_LIBS) \
- $(SPEEX_LIBS) \
- $(OSIP_LIBS)
-
linphonecsh_SOURCES = shell.c
linphonecsh_CFLAGS = $(CONSOLE_FLAGS)
linphonecsh_LDADD = $(ORTP_LIBS)
}
}
+static void call_released(SalOp *op){
+ LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
+ linphone_call_set_state(call,LinphoneCallReleased,"Call released");
+}
+
static void auth_requested(SalOp *h, const char *realm, const char *username){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username);
call_updating,
call_terminated,
call_failure,
+ call_released,
auth_requested,
auth_success,
register_success,
if (ms_list_size(lc->calls)==0)
linphone_core_notify_all_friends(lc,lc->presence_mode);
- 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);
}
const char *linphone_call_state_to_string(LinphoneCallState cs){
return "LinphoneCallIncomingEarlyMedia";
case LinphoneCallUpdated:
return "LinphoneCallUpdated";
+ case LinphoneCallReleased:
+ return "LinphoneCallReleased";
}
return "undefined state";
}
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message){
LinphoneCore *lc=call->core;
- bool_t finalize_call=FALSE;
+
if (call->state!=cstate){
ms_message("Call %p: moving from state %s to %s",call,linphone_call_state_to_string(call->state),
linphone_call_state_to_string(cstate));
call->state=cstate;
}
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
- finalize_call=TRUE;
- linphone_call_ref(call);
linphone_call_set_terminated (call);
}
if (lc->vtable.call_state_changed)
lc->vtable.call_state_changed(lc,call,cstate,message);
- if (finalize_call)
+ if (cstate==LinphoneCallReleased){
+ 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);
+ }
}
}
jitt_comp=lp_config_get_int(lc->config,"rtp","audio_jitt_comp",60);
linphone_core_set_audio_jittcomp(lc,jitt_comp);
jitt_comp=lp_config_get_int(lc->config,"rtp","video_jitt_comp",60);
+ if (jitt_comp==0) jitt_comp=60;
+ lc->rtp_conf.video_jitt_comp=jitt_comp;
nortp_timeout=lp_config_get_int(lc->config,"rtp","nortp_timeout",30);
linphone_core_set_nortp_timeout(lc,nortp_timeout);
rtp_no_xmit_on_audio_mute=lp_config_get_int(lc->config,"rtp","rtp_no_xmit_on_audio_mute",FALSE);
LinphoneCallPausedByRemote, /**<The call is paused by remote end*/
LinphoneCallUpdatedByRemote, /**<The call's parameters are updated, used for example when video is asked by remote */
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
- LinphoneCallUpdated /**<The remote accepted the call update initiated by us */
+ LinphoneCallUpdated, /**<The remote accepted the call update initiated by us */
+ LinphoneCallReleased /**< The call object is no more retained by the core */
} LinphoneCallState;
const char *linphone_call_state_to_string(LinphoneCallState cs);
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE is received*/
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
+typedef void (*SalOnCallReleased)(SalOp *salop);
typedef void (*SalOnAuthRequested)(SalOp *op, const char *realm, const char *username);
typedef void (*SalOnAuthSuccess)(SalOp *op, const char *realm, const char *username);
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
SalOnCallUpdating call_updating;
SalOnCallTerminated call_terminated;
SalOnCallFailure call_failure;
+ SalOnCallReleased call_released;
SalOnAuthRequested auth_requested;
SalOnAuthSuccess auth_success;
SalOnRegisterSuccess register_success;
ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
if (ctx->callbacks.call_terminated==NULL)
ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
+ if (ctx->callbacks.call_released==NULL)
+ ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
if (ctx->callbacks.call_updating==NULL)
ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
if (ctx->callbacks.auth_requested==NULL)
if (err!=0){
ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
}
- sal_remove_call(h->base.root,h);
- h->cid=-1;
return 0;
}
if (ev->request){
osip_from_to_str(ev->request->from,&from);
}
- sal_remove_call(sal,op);
- op->cid=-1;
sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
if (from) osip_free(from);
}
ms_warning("No op associated to this call_released()");
return;
}
- op->cid=-1;
- if (op->did==-1)
+ if (op->did==-1) {
sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487);
+ }
+ sal->callbacks.call_released(op);
}
static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
-Subproject commit fa8cbea18aae52d4bafc948687d678dfe453b628
+Subproject commit 664e9338cf0f963ef6ab6caad9679abcdfeb60c9