From 35ab327fb2fed019f920adb1bfc4ad60a3677b01 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 26 Mar 2012 15:21:32 +0200 Subject: [PATCH 01/23] Update current_call before notifiying call state change for LinphoneCallStreamsRunning --- coreapi/callbacks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 63bff23a9..5ffd43e44 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -368,9 +368,9 @@ static void call_accepted(SalOp *op){ } } linphone_core_update_streams (lc,call,md); - linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running"); if (!call->current_params.in_conference) lc->current_call=call; + linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running"); } }else{ /*send a bye*/ From 8ffeb3eb7c7e5738883f6c247330316753bf173e Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Mon, 26 Mar 2012 15:22:20 +0200 Subject: [PATCH 02/23] Expose ms2 MS_VIDEO_DECODER_FIRST_IMAGE_DECODED event to application --- coreapi/linphonecall.c | 8 +++++++- coreapi/linphonecore.h | 5 ++++- mediastreamer2 | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4872a4cdc..bf96a0400 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -842,12 +842,18 @@ static void rendercb(void *data, const MSPicture *local, const MSPicture *remote #ifdef VIDEO_ENABLED static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const unsigned int event_id, const void *args){ + LinphoneCall* call = (LinphoneCall*) user_pointer; ms_warning("In linphonecall.c: video_stream_event_cb"); switch (event_id) { case MS_VIDEO_DECODER_DECODING_ERRORS: ms_warning("Case is MS_VIDEO_DECODER_DECODING_ERRORS"); - linphone_call_send_vfu_request((LinphoneCall*) user_pointer); + linphone_call_send_vfu_request(call); break; + case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED: + ms_message("First video frame decoded successfully"); + if (call->core->vtable.call_first_video_frame != NULL) + call->core->vtable.call_first_video_frame(call->core, call); + break; default: ms_warning("Unhandled event %i", event_id); break; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 35fa25ad3..ea14d1596 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -613,7 +613,9 @@ typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int d typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); /** Callback prototype */ typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); - +/** Callback prototype */ +typedef void (*CallFirstVideoFrameCb)(struct _LinphoneCore *lc, LinphoneCall *call); + /** * This structure holds all callbacks that the application should implement. * None is mandatory. @@ -637,6 +639,7 @@ typedef struct _LinphoneVTable{ DisplayUrlCb display_url; ShowInterfaceCb show; /**< Notifies the application that it should show up*/ CallEncryptionChangedCb call_encryption_changed; /** Date: Tue, 27 Mar 2012 09:14:07 +0200 Subject: [PATCH 03/23] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index ef76a73e3..992399ad9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ef76a73e369e5afe9d7172b4330ebce2b2aee0ae +Subproject commit 992399ad92032dd5da35c84ec0a14249c8af5144 From 9a21860f49a6c4c52f5aafbcba84cf960d94b400 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 27 Mar 2012 15:22:57 +0200 Subject: [PATCH 04/23] Add 'video_enabled' information to call log --- coreapi/linphonecall.c | 1 + coreapi/linphonecore.c | 2 ++ coreapi/linphonecore.h | 1 + mediastreamer2 | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index bf96a0400..61a528d2a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1337,6 +1337,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut call->current_params.has_video=FALSE; if (call->videostream!=NULL) { linphone_call_start_video_stream(call,cname,all_inputs_muted); + call->log->video_enabled = TRUE; } call->all_muted=all_inputs_muted; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 63be1a7fc..bee7ad5fe 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -132,6 +132,7 @@ void call_logs_write_to_config_file(LinphoneCore *lc){ lp_config_set_int(cfg,logsection,"duration",cl->duration); if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey); lp_config_set_float(cfg,logsection,"quality",cl->quality); + lp_config_set_int(cfg,logsection,"video_enabled", cl->video_enabled); } for(;imax_call_logs;++i){ snprintf(logsection,sizeof(logsection),"call_log_%i",i); @@ -160,6 +161,7 @@ static void call_logs_read_from_config_file(LinphoneCore *lc){ tmp=lp_config_get_string(cfg,logsection,"refkey",NULL); if (tmp) cl->refkey=ms_strdup(tmp); cl->quality=lp_config_get_float(cfg,logsection,"quality",-1); + cl->video_enabled=lp_config_get_int(cfg,logsection,"video_enabled",0); lc->call_logs=ms_list_append(lc->call_logs,cl); }else break; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index ea14d1596..b7ceb87dd 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -153,6 +153,7 @@ typedef struct _LinphoneCallLog{ rtp_stats_t local_stats; rtp_stats_t remote_stats; float quality; + int video_enabled; struct _LinphoneCore *lc; } LinphoneCallLog; diff --git a/mediastreamer2 b/mediastreamer2 index 992399ad9..513945c97 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 992399ad92032dd5da35c84ec0a14249c8af5144 +Subproject commit 513945c9781dbb9ae6905bb7fa80db2665f64d01 From 2cb5c30f98ba04071dfcfa21d2c9a9bf1a744ae9 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 27 Mar 2012 15:56:12 +0200 Subject: [PATCH 05/23] Update RPM spec (use git version when it is possible) --- linphone.spec.in | 2 +- mediastreamer2 | 2 +- oRTP | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/linphone.spec.in b/linphone.spec.in index ff79974e6..44e3f5f00 100644 --- a/linphone.spec.in +++ b/linphone.spec.in @@ -11,7 +11,7 @@ Name: linphone Version: @VERSION@ -Release: %(git describe --tags | sed 's/.*-\([0-9]*\)-g.*/\1/' || echo '1')%{?dist} +Release: %(git describe --tags --abbrev=40 | sed -rn 's/^.*-([0-9]+)-g[a-z0-9]{40}$/\1/p' || echo '1')%{?dist} Summary: Phone anywhere in the whole world by using the Internet Group: Applications/Communications diff --git a/mediastreamer2 b/mediastreamer2 index 513945c97..9d722a145 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 513945c9781dbb9ae6905bb7fa80db2665f64d01 +Subproject commit 9d722a1456c8574b385fac0eadf4ad6a4067637b diff --git a/oRTP b/oRTP index 3fb614e2e..99cbcd905 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 3fb614e2ed15803f2c96c223cceb5545a60f2431 +Subproject commit 99cbcd905d357fd3a297f8d0e2aa4698c11c805a From 00984708fdda2c97b19b1f056efcaa35c800f8b1 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Tue, 27 Mar 2012 16:19:45 +0200 Subject: [PATCH 06/23] fix linphone-devel mediastream-devel dependency --- linphone.spec.in | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/linphone.spec.in b/linphone.spec.in index 44e3f5f00..86929b575 100644 --- a/linphone.spec.in +++ b/linphone.spec.in @@ -27,7 +27,7 @@ BuildRequires: gtk2-devel BuildRequires: libeXosip2-devel speex-devel gettext BuildRequires: intltool gettext-devel %if %{video} -BuildRequires: ffmpeg-devel SDL-devel +BuildRequires: ffmpeg-devel SDL-devel %endif %description @@ -35,12 +35,12 @@ Linphone is a SIP compliant audio & video phone. It can be used to run calls over the internet. It has a gtk+ and console interface. %package devel -Summary: Development libraries for linphone -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} -Requires: ortp-devel = @ORTP_VERSION@ -Requires: mediastreamer2-devel = @MS2_VERSION@ -Requires: glib2-devel +Summary: Development libraries for linphone +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Requires: ortp-devel = @ORTP_VERSION@ +Requires: mediastreamer-devel = @MS2_VERSION@ +Requires: glib2-devel %description devel Libraries and headers required to develop software with linphone. From 3a8b6a943c924d3049ed1980721959ab628d471d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 29 Mar 2012 10:43:46 +0200 Subject: [PATCH 07/23] fix mac os build (AM_GNU_GETTEXT was adding flags to CPPFLAGS) --- configure.ac | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ce3604451..7a523eecb 100644 --- a/configure.ac +++ b/configure.ac @@ -102,9 +102,13 @@ AC_SUBST(ALL_LINGUAS) AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages]) if test "$mingw_found" != "yes" ; then -dnl gettext macro does not work properly under mingw. And we want to use the one provided by GTK. -AM_GNU_GETTEXT([external]) -LIBS="$LIBS $LIBINTL" + dnl gettext macro does not work properly under mingw. And we want to use the one provided by GTK. + + dnl AM_GNU_GETTEXT pollutes CPPFLAGS: workaround this. + CPPFLAGS_save=$CPPFLAGS + AM_GNU_GETTEXT([external]) + CPPFLAGS=$CPPFLAGS_save + LIBS="$LIBS $LIBINTL" else AC_DEFINE(ENABLE_NLS,1,[Tells whether localisation is possible]) AC_DEFINE(HAVE_GETTEXT,1,[Tells wheter localisation is possible]) From 48f34568c9fab1cbc11e3c6030fca07d175d488d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 29 Mar 2012 15:09:52 +0200 Subject: [PATCH 08/23] implement notifications when doing transfers --- configure.ac | 2 +- coreapi/callbacks.c | 40 +++++++++++++- coreapi/linphonecall.c | 5 ++ coreapi/linphonecore.c | 10 +++- coreapi/linphonecore.h | 9 ++- coreapi/presence.c | 2 +- coreapi/private.h | 5 +- coreapi/sal.h | 17 ++++-- coreapi/sal_eXosip2.c | 121 +++++++++++++++++++++++++++++------------ gtk/incall_view.c | 22 ++++++++ gtk/linphone.h | 1 + gtk/main.c | 6 ++ mediastreamer2 | 2 +- 13 files changed, 191 insertions(+), 51 deletions(-) diff --git a/configure.ac b/configure.ac index 7a523eecb..2bead21dd 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ if test "$LINPHONE_EXTRA_VERSION" != "" ;then LINPHONE_VERSION=$LINPHONE_VERSION.${LINPHONE_EXTRA_VERSION} fi -LIBLINPHONE_SO_CURRENT=4 dnl increment this number when you add/change/remove an interface +LIBLINPHONE_SO_CURRENT=5 dnl increment this number when you add/change/remove an interface LIBLINPHONE_SO_REVISION=0 dnl increment this number when you change source code, without changing interfaces; set to 0 when incrementing CURRENT LIBLINPHONE_SO_AGE=0 dnl increment this number when you add an interface, set to 0 if you remove an interface diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 5ffd43e44..8d41da101 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -323,6 +323,7 @@ static void call_accepted(SalOp *op){ call->state==LinphoneCallOutgoingRinging || call->state==LinphoneCallOutgoingEarlyMedia){ linphone_call_set_state(call,LinphoneCallConnected,"Connected"); + if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call); } if (md && !sal_media_description_empty(md)){ if (sal_media_description_has_dir(md,SalStreamSendOnly) || @@ -591,6 +592,10 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de } else { linphone_call_set_state(call,LinphoneCallError,msg); } + if (call->referer && linphone_call_get_state(call->referer)==LinphoneCallPaused && call->referer->was_automatically_paused){ + /*resume to the call that send us the refer automatically*/ + linphone_core_resume_call(lc,call->referer); + } } static void call_released(SalOp *op){ @@ -744,12 +749,11 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){ if (call->state!=LinphoneCallPaused){ ms_message("Automatically pausing current call to accept transfer."); linphone_core_pause_call(lc,call); + call->was_automatically_paused=TRUE; } linphone_core_start_refered_call(lc,call); - sal_call_accept_refer(op); }else if (lc->vtable.refer_received){ lc->vtable.refer_received(lc,referto); - sal_call_accept_refer(op); } } @@ -766,7 +770,7 @@ static void notify(SalOp *op, const char *from, const char *msg){ lc->vtable.notify_recv(lc,call,from,msg); } -static void notify_presence(SalOp *op, SalSubscribeState ss, SalPresenceStatus status, const char *msg){ +static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceStatus status, const char *msg){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); linphone_notify_recv(lc,op,ss,status); } @@ -795,6 +799,35 @@ static void ping_reply(SalOp *op){ } } +static void notify_refer(SalOp *op, SalReferStatus status){ + LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); + LinphoneCall *call=(LinphoneCall*) sal_op_get_user_pointer(op); + LinphoneCallState cstate; + if (call==NULL) { + ms_warning("Receiving notify_refer for unknown call."); + return ; + } + switch(status){ + case SalReferTrying: + cstate=LinphoneCallOutgoingProgress; + break; + case SalReferSuccess: + cstate=LinphoneCallConnected; + break; + case SalReferFailed: + cstate=LinphoneCallError; + break; + default: + cstate=LinphoneCallError; + } + if (lc->vtable.transfer_state_changed) + lc->vtable.transfer_state_changed(lc,call,cstate); + if (cstate==LinphoneCallConnected){ + /*automatically terminate the call as the transfer is complete.*/ + linphone_core_terminate_call(lc,call); + } +} + SalCallbacks linphone_sal_callbacks={ call_received, call_ringing, @@ -814,6 +847,7 @@ SalCallbacks linphone_sal_callbacks={ text_received, notify, notify_presence, + notify_refer, subscribe_received, subscribe_closed, ping_reply diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 61a528d2a..433d0ce26 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -332,6 +332,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr discover_mtu(lc,linphone_address_get_domain (to)); if (params->referer){ sal_call_set_referer(call->op,params->referer->op); + call->referer=linphone_call_ref(params->referer); } return call; } @@ -401,6 +402,10 @@ static void linphone_call_set_terminated(LinphoneCall *call){ linphone_core_stop_dtmf(lc); call->ringing_beep=FALSE; } + if (call->referer){ + linphone_call_unref(call->referer); + call->referer=NULL; + } } void linphone_call_fix_call_parameters(LinphoneCall *call){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index bee7ad5fe..904f6a6c8 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1943,12 +1943,20 @@ const char * linphone_core_get_route(LinphoneCore *lc){ void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call){ if (call->refer_pending){ LinphoneCallParams *cp=linphone_core_create_default_call_parameters(lc); + LinphoneCall *newcall; cp->has_video &= !!lc->video_policy.automatically_initiate; cp->referer=call; ms_message("Starting new call to refered address %s",call->refer_to); call->refer_pending=FALSE; - linphone_core_invite_with_params(lc,call->refer_to,cp); + newcall=linphone_core_invite_with_params(lc,call->refer_to,cp); linphone_call_params_destroy(cp); + if (newcall) linphone_core_notify_refer_state(lc,call,newcall); + } +} + +void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, LinphoneCall *newcall){ + if (referer->op!=NULL){ + sal_call_notify_refer_state(referer->op,newcall ? newcall->op : NULL); } } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b7ceb87dd..4581d24fa 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -616,7 +616,9 @@ typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); /** Callback prototype */ typedef void (*CallFirstVideoFrameCb)(struct _LinphoneCore *lc, LinphoneCall *call); - +/** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */ +typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state); + /** * This structure holds all callbacks that the application should implement. * None is mandatory. @@ -632,6 +634,9 @@ typedef struct _LinphoneVTable{ TextMessageReceived text_received; /**< A text message has been received */ DtmfReceived dtmf_received; /**< A dtmf has been received received */ ReferReceived refer_received; /**< An out of call refer was received */ + CallEncryptionChangedCb call_encryption_changed; /**did,"SIP/2.0 100 Trying\r\n"); + } + else if (newcall->cid!=-1){ + if (newcall->did==-1){ + /* not yet established*/ + if (!newcall->terminated){ + /* in progress*/ + send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n"); + } + }else{ + if (!newcall->terminated){ + send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n"); + } + } + } + return 0; +} + int sal_ping(SalOp *op, const char *from, const char *to){ osip_message_t *options=NULL; @@ -748,26 +787,6 @@ int sal_ping(SalOp *op, const char *from, const char *to){ return -1; } -int sal_call_accept_refer(SalOp *op){ - osip_message_t *msg=NULL; - int err=0; - eXosip_lock(); - err = eXosip_call_build_notify(op->did,EXOSIP_SUBCRSTATE_ACTIVE,&msg); - if(msg != NULL) - { - osip_message_set_header(msg,(const char *)"event","refer"); - osip_message_set_content_type(msg,"message/sipfrag"); - osip_message_set_body(msg,"SIP/2.0 100 Trying",sizeof("SIP/2.0 100 Trying")); - eXosip_call_send_request(op->did,msg); - } - else - { - ms_error("could not get a notify built\n"); - } - eXosip_unlock(); - return err; -} - int sal_call_refer(SalOp *h, const char *refer_to){ osip_message_t *msg=NULL; int err=0; @@ -1517,6 +1536,51 @@ static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){ } } +void process_notify(Sal *sal, eXosip_event_t *ev){ + osip_header_t *h=NULL; + char *from=NULL; + SalOp *op=find_op(sal,ev); + osip_message_t *ans=NULL; + + ms_message("Receiving NOTIFY request !"); + osip_from_to_str(ev->request->from,&from); + osip_message_header_get_byname(ev->request,"Event",0,&h); + if(h){ + osip_body_t *body=NULL; + //osip_content_type_t *ct=NULL; + osip_message_get_body(ev->request,0,&body); + //ct=osip_message_get_content_type(ev->request); + if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){ + /*special handling of refer events*/ + if (body && body->body){ + osip_message_t *msg; + osip_message_init(&msg); + if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){ + int code=osip_message_get_status_code(msg); + if (code==100){ + sal->callbacks.notify_refer(op,SalReferTrying); + }else if (code==200){ + sal->callbacks.notify_refer(op,SalReferSuccess); + }else if (code>=400){ + sal->callbacks.notify_refer(op,SalReferFailed); + } + } + osip_message_free(msg); + } + }else{ + /*generic handling*/ + sal->callbacks.notify(op,from,h->hvalue); + } + } + /*answer that we received the notify*/ + eXosip_lock(); + eXosip_call_build_answer(ev->tid,200,&ans); + if (ans) + eXosip_call_send_answer(ev->tid,200,ans); + eXosip_unlock(); + osip_free(from); +} + static void call_message_new(Sal *sal, eXosip_event_t *ev){ osip_message_t *ans=NULL; if (ev->request){ @@ -1559,22 +1623,7 @@ static void call_message_new(Sal *sal, eXosip_event_t *ev){ ms_message("Receiving REFER request !"); process_refer(sal,op,ev); }else if(MSG_IS_NOTIFY(ev->request)){ - osip_header_t *h=NULL; - char *from=NULL; - SalOp *op=find_op(sal,ev); - - ms_message("Receiving NOTIFY request !"); - osip_from_to_str(ev->request->from,&from); - osip_message_header_get_byname(ev->request,"Event",0,&h); - if(h) - sal->callbacks.notify(op,from,h->hvalue); - /*answer that we received the notify*/ - eXosip_lock(); - eXosip_call_build_answer(ev->tid,200,&ans); - if (ans) - eXosip_call_send_answer(ev->tid,200,ans); - eXosip_unlock(); - osip_free(from); + process_notify(sal,ev); }else if (MSG_IS_OPTIONS(ev->request)){ eXosip_lock(); eXosip_call_build_answer(ev->tid,200,&ans); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index d693ac149..d19dba8c2 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -579,6 +579,28 @@ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_m linphone_gtk_terminate_conference_participant(call); } +void linphone_gtk_in_call_view_set_transfer_status(LinphoneCall *call,LinphoneCallState cstate){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + if (callview){ + GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); + const char *transfer_status="unknown"; + switch(cstate){ + case LinphoneCallOutgoingProgress: + transfer_status=_("Transfer in progress"); + break; + case LinphoneCallConnected: + transfer_status=_("Transfer done."); + break; + case LinphoneCallError: + transfer_status=_("Transfer failed."); + break; + default: + break; + } + gtk_label_set_text(GTK_LABEL(duration),transfer_status); + } +} + void linphone_gtk_draw_mute_button(GtkButton *button, gboolean active){ g_object_set_data(G_OBJECT(button),"active",GINT_TO_POINTER(active)); if (active){ diff --git a/gtk/linphone.h b/gtk/linphone.h index 7074bc87d..d4cafe28f 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -107,6 +107,7 @@ void linphone_gtk_in_call_view_update_duration(LinphoneCall *call); void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg); void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call); void linphone_gtk_in_call_view_set_paused(LinphoneCall *call); +void linphone_gtk_in_call_view_set_transfer_status(LinphoneCall *call,LinphoneCallState cstate); void linphone_gtk_mute_clicked(GtkButton *button); void linphone_gtk_enable_mute_button(GtkButton *button, gboolean sensitive); void linphone_gtk_enable_hold_button(LinphoneCall *call, gboolean sensitive, gboolean holdon); diff --git a/gtk/main.c b/gtk/main.c index 60c4556d7..819195268 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -63,6 +63,7 @@ static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const ch static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl); static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg); static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token); +static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate); static gboolean linphone_gtk_auto_answer(LinphoneCall *call); static void linphone_gtk_status_icon_set_blinking(gboolean val); @@ -225,6 +226,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, vtable.refer_received=linphone_gtk_refer_received; vtable.buddy_info_updated=linphone_gtk_buddy_info_updated; vtable.call_encryption_changed=linphone_gtk_call_encryption_changed; + vtable.transfer_state_changed=linphone_gtk_transfer_state_changed; linphone_core_set_user_agent("Linphone", LINPHONE_VERSION); the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL); @@ -1133,6 +1135,10 @@ static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall linphone_gtk_in_call_view_show_encryption(call); } +static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate){ + linphone_gtk_in_call_view_set_transfer_status(call,cstate); +} + static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistrationState rs){ GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities")); GtkTreeModel *model=gtk_combo_box_get_model(box); diff --git a/mediastreamer2 b/mediastreamer2 index 9d722a145..1b517a0bc 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9d722a1456c8574b385fac0eadf4ad6a4067637b +Subproject commit 1b517a0bc1d6559267143130d137d0252a05f752 From 9c0fb8ce7189334c36e86b638ed72e5199a7118a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 29 Mar 2012 15:55:55 +0200 Subject: [PATCH 09/23] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 1b517a0bc..7af64431d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1b517a0bc1d6559267143130d137d0252a05f752 +Subproject commit 7af64431dde94b21e0313ced873726462b4f5f32 From d481382fb4c55300737d1f6fc02cecb4d509cc60 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 30 Mar 2012 13:06:19 +0200 Subject: [PATCH 10/23] Moved the 'video frame decoded' callback from Core to LinphoneCall --- coreapi/linphonecall.c | 14 +++++++++++--- coreapi/linphonecore.h | 10 ++++++---- coreapi/private.h | 7 +++++++ mediastreamer2 | 2 +- 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 433d0ce26..35e840902 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -856,8 +856,8 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u break; case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED: ms_message("First video frame decoded successfully"); - if (call->core->vtable.call_first_video_frame != NULL) - call->core->vtable.call_first_video_frame(call->core, call); + if (call->nextVideoFrameDecoded._func != NULL) + call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data); break; default: ms_warning("Unhandled event %i", event_id); @@ -866,6 +866,14 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u } #endif +void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data) { + call->nextVideoFrameDecoded._func = cb; + call->nextVideoFrameDecoded._user_data = user_data; +#ifdef VIDEO_ENABLED + ms_filter_call_method_noarg(call->videostream->decoder, MS_VIDEO_DECODER_RESET_FIRST_IMAGE_NOTIFICATION); +#endif +} + void linphone_call_init_media_streams(LinphoneCall *call){ LinphoneCore *lc=call->core; SalMediaDescription *md=call->localdesc; @@ -1284,6 +1292,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna cam=get_nowebcam_device(); } if (!is_inactive){ + call->log->video_enabled = TRUE; video_stream_set_direction (call->videostream, dir); ms_message("%s lc rotation:%d\n", __FUNCTION__, lc->device_rotation); video_stream_set_device_rotation(call->videostream, lc->device_rotation); @@ -1342,7 +1351,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut call->current_params.has_video=FALSE; if (call->videostream!=NULL) { linphone_call_start_video_stream(call,cname,all_inputs_muted); - call->log->video_enabled = TRUE; } call->all_muted=all_inputs_muted; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 4581d24fa..9ed629710 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -226,6 +226,9 @@ typedef struct _LinphoneVideoPolicy LinphoneVideoPolicy; **/ struct _LinphoneCall; typedef struct _LinphoneCall LinphoneCall; + +/** Callback prototype */ +typedef void (*LinphoneCallCbFunc)(struct _LinphoneCall *call,void * user_data); /** * LinphoneCallState enum represents the different state a call can reach into. @@ -287,6 +290,8 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t void linphone_call_send_vfu_request(LinphoneCall *call); void *linphone_call_get_user_pointer(LinphoneCall *call); void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); +void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data); + /** * Enables or disable echo cancellation for this call * @param call @@ -614,8 +619,6 @@ typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int d typedef void (*ReferReceived)(struct _LinphoneCore *lc, const char *refer_to); /** Callback prototype */ typedef void (*BuddyInfoUpdated)(struct _LinphoneCore *lc, LinphoneFriend *lf); -/** Callback prototype */ -typedef void (*CallFirstVideoFrameCb)(struct _LinphoneCore *lc, LinphoneCall *call); /** Callback prototype for in progress transfers. The new_call_state is the state of the call resulting of the transfer, at the other party. */ typedef void (*LinphoneTransferStateChanged)(struct _LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state); @@ -635,8 +638,7 @@ typedef struct _LinphoneVTable{ DtmfReceived dtmf_received; /**< A dtmf has been received received */ ReferReceived refer_received; /**< An out of call refer was received */ CallEncryptionChangedCb call_encryption_changed; /** Date: Fri, 30 Mar 2012 15:44:58 +0200 Subject: [PATCH 11/23] don't try to send text through not yet established dialogs --- coreapi/chat.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index d90cf61e4..9847c2c3b 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -52,15 +52,20 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ const char *route=NULL; const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route); - SalOp *op; + SalOp *op=NULL; LinphoneCall *call; - if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL) - { - ms_message("send SIP message into the call\n"); - op = call->op; + if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){ + if (call->state==LinphoneCallConnected || + call->state==LinphoneCallStreamsRunning || + call->state==LinphoneCallPaused || + call->state==LinphoneCallPausing || + call->state==LinphoneCallPausedByRemote){ + ms_message("send SIP message through the existing call."); + op = call->op; + } } - else - { + if (op==NULL){ + /*sending out of calls*/ op = sal_op_new(cr->lc->sal); sal_op_set_route(op,route); if (cr->op!=NULL){ From 478cb5104ce4e58793ac2cc1feed0c3bdcec576c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 31 Mar 2012 16:32:31 +0200 Subject: [PATCH 12/23] update ms2 to repair build --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 624178446..0796641e6 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 6241784466c0032b701cbb00d4ddab1db120bbf0 +Subproject commit 0796641e644123ac2e38384bdf9f6d66638ecbdc From 1f53d4f5d88493b9fb09be75f67a25960b1c526a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 2 Apr 2012 17:12:54 +0200 Subject: [PATCH 13/23] update oRTP for zrtp and srtp bugfixes --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index 99cbcd905..04570bd7a 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 99cbcd905d357fd3a297f8d0e2aa4698c11c805a +Subproject commit 04570bd7a02f9baa682c4667fbba16e8c951b62b From aab6c70d934e40381e8b32504dbe2848d9bd1f7f Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 3 Apr 2012 10:49:23 +0200 Subject: [PATCH 14/23] introduce use of card preferred sample rate, usefull for IOS to speed-up call estbalishement --- coreapi/callbacks.c | 1 + coreapi/linphonecall.c | 14 ++++++++++---- coreapi/sal.h | 1 + mediastreamer2 | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 63bff23a9..a4181cfa0 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -276,6 +276,7 @@ static void call_ringing(SalOp *h){ if (lc->ringstream!=NULL) return; /*already ringing !*/ if (lc->sound_conf.play_sndcard!=NULL){ MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard; + if (call->localdesc->streams[0].max_rate>0) ms_snd_card_set_preferred_sample_rate(ringcard, call->localdesc->streams[0].max_rate); lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard); } ms_message("Remote ringing..."); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 82d4e5098..6ec119105 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/msfileplayer.h" #include "mediastreamer2/msjpegwriter.h" #include "mediastreamer2/mseventqueue.h" +#include "mediastreamer2/mssndcard.h" #ifdef VIDEO_ENABLED static MSWebCam *get_nowebcam_device(){ @@ -172,9 +173,10 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t propagate_encryption_changed(call); } -static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){ +static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit,int* max_sample_rate){ MSList *l=NULL; const MSList *it; + if (max_sample_rate) *max_sample_rate=0; for(it=codecs;it!=NULL;it=it->next){ PayloadType *pt=(PayloadType*)it->data; if (pt->flags & PAYLOAD_TYPE_ENABLED){ @@ -184,6 +186,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw } if (linphone_core_check_payload_type_usability(lc,pt)){ l=ms_list_append(l,payload_type_clone(pt)); + if (max_sample_rate && payload_type_get_rate(pt)>*max_sample_rate) *max_sample_rate=payload_type_get_rate(pt); } } } @@ -199,6 +202,7 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li const char *username=linphone_address_get_username (addr); SalMediaDescription *md=sal_media_description_new(); + md->session_id=session_id; md->session_ver=session_ver; md->nstreams=1; @@ -213,10 +217,11 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li SalProtoRtpSavp : SalProtoRtpAvp; md->streams[0].type=SalAudio; md->streams[0].ptime=lc->net_conf.down_ptime; - l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw); + l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate); pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event")); l=ms_list_append(l,pt); md->streams[0].payloads=l; + if (call->params.has_video){ @@ -224,7 +229,7 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li md->streams[1].port=call->video_port; md->streams[1].proto=md->streams[0].proto; md->streams[1].type=SalVideo; - l=make_codec_list(lc,lc->codecs_conf.video_codecs,0); + l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL); md->streams[1].payloads=l; } @@ -1154,7 +1159,8 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna captcard=playcard=NULL; } use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc); - + if (playcard && stream->max_rate>0) ms_snd_card_set_preferred_sample_rate(playcard, stream->max_rate); + if (captcard && stream->max_rate>0) ms_snd_card_set_preferred_sample_rate(captcard, stream->max_rate); audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc); audio_stream_start_full( call->audiostream, diff --git a/coreapi/sal.h b/coreapi/sal.h index 1ae18a9d4..e74e80c68 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -134,6 +134,7 @@ typedef struct SalStreamDescription{ SalStreamDir dir; SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX]; unsigned int crypto_local_tag; + int max_rate; } SalStreamDescription; #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4 diff --git a/mediastreamer2 b/mediastreamer2 index d1e350535..3e43a4991 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d1e3505352c469f91333f65e43cda48560b26a91 +Subproject commit 3e43a499150a684eef2d775e3fe8ff4ddf72b769 From cc40a4f2a7f6fc6eab689208804868d836ddcd8e Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 3 Apr 2012 15:04:28 +0200 Subject: [PATCH 15/23] fix compilation issues --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3e43a4991..32adc29b6 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3e43a499150a684eef2d775e3fe8ff4ddf72b769 +Subproject commit 32adc29b6fbee450c2bfd307dd9642eaecff16ef From b06a202d82739f9e9d66a02104f79f8399ecb680 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 3 Apr 2012 15:35:42 +0200 Subject: [PATCH 16/23] fix: don't stop ringback in linphone_core_stop_dtmf_stream(). --- coreapi/linphonecore.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 904f6a6c8..6f459b2be 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4583,8 +4583,10 @@ void linphone_core_start_dtmf_stream(LinphoneCore* lc) { } void linphone_core_stop_dtmf_stream(LinphoneCore* lc) { - if (lc->ringstream) ring_stop(lc->ringstream); - lc->ringstream=NULL; + if (lc->ringstream && dmfs_playing_start_time!=0) { + ring_stop(lc->ringstream); + lc->ringstream=NULL; + } } int linphone_core_get_max_calls(LinphoneCore *lc) { From 9b421bfd4358c3189ea717f2a2c4050eb0bdcb01 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 3 Apr 2012 16:04:57 +0200 Subject: [PATCH 17/23] fix broken compile --- coreapi/linphonecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6f459b2be..f99cb9c29 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4583,7 +4583,7 @@ void linphone_core_start_dtmf_stream(LinphoneCore* lc) { } void linphone_core_stop_dtmf_stream(LinphoneCore* lc) { - if (lc->ringstream && dmfs_playing_start_time!=0) { + if (lc->ringstream && lc->dmfs_playing_start_time!=0) { ring_stop(lc->ringstream); lc->ringstream=NULL; } From 05e04e20594d5ace744cb8aee3cc386376cefb72 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 3 Apr 2012 15:34:03 +0200 Subject: [PATCH 18/23] Add transfer_state property to LinphoneCall --- coreapi/callbacks.c | 4 ++-- coreapi/linphonecall.c | 13 +++++++++++++ coreapi/linphonecore.c | 5 ++++- coreapi/linphonecore.h | 1 + coreapi/private.h | 2 ++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 34fd552af..c58b42e73 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -420,6 +420,7 @@ static void call_resumed(LinphoneCore *lc, LinphoneCall *call){ if(lc->vtable.display_status) lc->vtable.display_status(lc,_("We have been resumed.")); linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)"); + linphone_call_set_transfer_state(call, LinphoneCallIdle); } static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){ @@ -821,8 +822,7 @@ static void notify_refer(SalOp *op, SalReferStatus status){ default: cstate=LinphoneCallError; } - if (lc->vtable.transfer_state_changed) - lc->vtable.transfer_state_changed(lc,call,cstate); + linphone_call_set_transfer_state(call, cstate); if (cstate==LinphoneCallConnected){ /*automatically terminate the call as the transfer is complete.*/ linphone_core_terminate_call(lc,call); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 9c3ecfd11..d41c6cdad 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -295,6 +295,7 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, call->magic=linphone_call_magic; call->refcnt=1; call->state=LinphoneCallIdle; + call->transfer_state = LinphoneCallIdle; call->start_time=time(NULL); call->media_start_time=0; call->log=linphone_call_log_new(call, from, to); @@ -1675,4 +1676,16 @@ void linphone_call_log_completed(LinphoneCall *call){ call_logs_write_to_config_file(lc); } +LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call) { + return call->transfer_state; +} + +void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state) { + if (state != call->transfer_state) { + LinphoneCore* lc = call->core; + call->transfer_state = state; + if (lc->vtable.transfer_state_changed) + lc->vtable.transfer_state_changed(lc, call, state); + } +} diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f99cb9c29..3a081d23d 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2262,6 +2262,7 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char sal_call_refer(call->op,real_url); ms_free(real_url); linphone_address_destroy(real_parsed_url); + linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); return 0; } @@ -2278,7 +2279,9 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char * close the call with us (the 'dest' call). **/ int linphone_core_transfer_call_to_another(LinphoneCore *lc, LinphoneCall *call, LinphoneCall *dest){ - return sal_call_refer_with_replaces (call->op,dest->op); + int result = sal_call_refer_with_replaces (call->op,dest->op); + linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit); + return result; } bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 9ed629710..d2860c3a2 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -291,6 +291,7 @@ void linphone_call_send_vfu_request(LinphoneCall *call); void *linphone_call_get_user_pointer(LinphoneCall *call); void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data); +LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call); /** * Enables or disable echo cancellation for this call diff --git a/coreapi/private.h b/coreapi/private.h index 425b51008..ec57eaf9c 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -100,6 +100,7 @@ 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*/ LinphoneCallState state; + LinphoneCallState transfer_state; /*idle if no transfer*/ LinphoneReason reason; int refcnt; void * user_pointer; @@ -142,6 +143,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *local, LinphoneAddress * remote); void linphone_call_log_completed(LinphoneCall *call); void linphone_call_log_destroy(LinphoneCallLog *cl); +void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state); void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos); From cb41acb925aaeb761154f3166ce3107f9051a674 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 3 Apr 2012 16:18:23 +0200 Subject: [PATCH 19/23] fix auto-resuming of call in case of transfer failures --- coreapi/callbacks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index c58b42e73..3f0ac8114 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -585,6 +585,10 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de lc->ringstream=NULL; } linphone_call_stop_media_streams (call); + if (call->referer && linphone_call_get_state(call->referer)==LinphoneCallPaused && call->referer->was_automatically_paused){ + /*resume to the call that send us the refer automatically*/ + linphone_core_resume_call(lc,call->referer); + } if (sr == SalReasonDeclined) { call->reason=LinphoneReasonDeclined; linphone_call_set_state(call,LinphoneCallEnd,"Call declined."); @@ -594,10 +598,6 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de } else { linphone_call_set_state(call,LinphoneCallError,msg); } - if (call->referer && linphone_call_get_state(call->referer)==LinphoneCallPaused && call->referer->was_automatically_paused){ - /*resume to the call that send us the refer automatically*/ - linphone_core_resume_call(lc,call->referer); - } } static void call_released(SalOp *op){ From e7123e495aa88c5432b1a7c21e5f9de39ef5bc90 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 3 Apr 2012 16:22:01 +0200 Subject: [PATCH 20/23] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 32adc29b6..3870493e9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 32adc29b6fbee450c2bfd307dd9642eaecff16ef +Subproject commit 3870493e9a59ddf7858cf4628dd86ec7a8b469d8 From 5d60fae67e3a524afcdaedfac5a3dc15333a3b07 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 4 Apr 2012 10:39:56 +0200 Subject: [PATCH 21/23] fix bug in incoming call timeout implementation --- coreapi/linphonecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3a081d23d..5854774ff 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1800,7 +1800,7 @@ void linphone_core_iterate(LinphoneCore *lc){ /*start the call even if the OPTIONS reply did not arrive*/ linphone_core_start_invite(lc,call,NULL); } - if (call->dir==LinphoneCallIncoming && call->state==LinphoneCallOutgoingRinging){ + if (call->state==LinphoneCallIncomingReceived){ elapsed=curtime-call->start_time; ms_message("incoming call ringing for %i seconds",elapsed); if (elapsed>lc->sip_conf.inc_timeout){ From 2111e92a393cd0cbf3934ea1de406904f0d34bca Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 4 Apr 2012 12:29:03 +0200 Subject: [PATCH 22/23] bugfix: do not retry without encryption when call is cancelled --- coreapi/callbacks.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 3f0ac8114..bde6a2f40 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -561,16 +561,18 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de int i; ms_message("Outgoing call failed with SRTP (SAVP) enabled - retrying with AVP"); linphone_call_stop_media_streams(call); - /* clear SRTP local params */ - call->params.media_encryption = LinphoneMediaEncryptionNone; - for(i=0; ilocaldesc->nstreams; i++) { - call->localdesc->streams[i].proto = SalProtoRtpAvp; - memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto)); + if (call->state==LinphoneCallOutgoingInit || call->state==LinphoneCallOutgoingProgress){ + /* clear SRTP local params */ + call->params.media_encryption = LinphoneMediaEncryptionNone; + for(i=0; ilocaldesc->nstreams; i++) { + call->localdesc->streams[i].proto = SalProtoRtpAvp; + memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto)); + } + linphone_core_start_invite(lc, call, NULL); } - linphone_core_start_invite(lc, call, NULL); return; } - msg=_("No common codecs"); + msg=_("Incompatible media parameters."); if (lc->vtable.display_status) lc->vtable.display_status(lc,msg); break; From 30eca09f41d40af19a67e64912a35bf1e313cd30 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Thu, 5 Apr 2012 12:43:41 +0200 Subject: [PATCH 23/23] add linphone_core_get_payload_type_number in api --- coreapi/linphonecore.h | 2 ++ coreapi/misc.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index d2860c3a2..0bca75ce9 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -792,6 +792,8 @@ int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate) ; +int linphone_core_get_payload_type_number(LinphoneCore *lc, PayloadType *pt); + const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt); bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, PayloadType *pt); diff --git a/coreapi/misc.c b/coreapi/misc.c index ea85f1036..41d4efac8 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -202,6 +202,10 @@ int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t return -1; } +int linphone_core_get_payload_type_number(LinphoneCore *lc, PayloadType *pt){ + return payload_type_get_number(pt); +} + const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt){ if (ms_filter_codec_supported(pt->mime_type)){ MSFilterDesc *desc=ms_filter_get_encoder(pt->mime_type);