From 68fa02580211e151d89b5d600f2d8072395a41d6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 30 May 2011 12:32:47 +0200 Subject: [PATCH 01/51] fix bug regarding calls that might be accepted while the application already declined it --- coreapi/linphonecall.c | 1 - coreapi/sal_eXosip2.c | 14 ++++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4230a156b..ab521aa7f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -223,7 +223,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro /* 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 */ diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 33ef079c9..869a7d8bb 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1015,13 +1015,12 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){ static int call_proceeding(Sal *sal, eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); - - if (op==NULL) { + + if (op==NULL || op->terminated==TRUE) { ms_warning("This call has been canceled."); eXosip_lock(); eXosip_call_terminate(ev->cid,ev->did); eXosip_unlock(); - op->terminated=TRUE; return -1; } if (ev->did>0) @@ -1056,9 +1055,12 @@ static void call_accepted(Sal *sal, eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); const char *contact; - if (op==NULL){ - ms_error("A closed call is accepted ?"); - return; + if (op==NULL || op->terminated==TRUE) { + ms_warning("This call has been already terminated."); + eXosip_lock(); + eXosip_call_terminate(ev->cid,ev->did); + eXosip_unlock(); + return ; } op->did=ev->did; From 4d7ab1c95d0ab3fddb9c1bf88e5860cb2b6a3cf6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 31 May 2011 10:34:34 +0200 Subject: [PATCH 02/51] fix crash because of payload types freed when receiving a new SDP (after early media for example), but media sessions are not restarted. --- coreapi/callbacks.c | 4 +++- coreapi/offeranswer.c | 2 +- mediastreamer2 | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 046f7edb5..bce577773 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -49,7 +49,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia /* we already started media: check if we really need to restart it*/ if (oldmd){ if (!media_parameters_changed(call,oldmd,new_md) && !call->playing_ringbacktone){ - sal_media_description_unref(oldmd); + /*as nothing has changed, keep the oldmd */ + call->resultdesc=oldmd; + sal_media_description_unref(new_md); if (call->all_muted){ ms_message("Early media finished, unmuting inputs..."); /*we were in early media, now we want to enable real media */ diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 5748a6d5b..34d21fc0f 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -96,7 +96,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t Indeed despite we must sent with the remote numbering, we must be able to receive with our local one. */ - newp=payload_type_clone(matched); + newp=payload_type_clone(newp); payload_type_set_number(newp,local_number); res=ms_list_append(res,newp); } diff --git a/mediastreamer2 b/mediastreamer2 index 285b4e9c7..3c348bc98 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 285b4e9c790f34a4cc1087af72425290c532c1df +Subproject commit 3c348bc98e990f0819b972a8b04d80da2d6d0d77 From 0e7407ad1151830a622cde20d091a0647581fed6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 31 May 2011 10:54:34 +0200 Subject: [PATCH 03/51] fix unused variables --- coreapi/linphonecore.c | 9 ++++----- coreapi/proxy.c | 4 ---- coreapi/sal_eXosip2.c | 5 ++--- gtk/friendlist.c | 9 ++++----- oRTP | 2 +- 5 files changed, 11 insertions(+), 18 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 4c6deea9a..2b8eb73e6 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1636,9 +1636,9 @@ void linphone_core_iterate(LinphoneCore *lc){ linphone_core_start_invite() */ calls=calls->next; if (call->state==LinphoneCallOutgoingInit && (curtime-call->start_time>=2)){ - /*start the call even if the OPTIONS reply did not arrive*/ - linphone_core_start_invite(lc,call,NULL); - } + /*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){ elapsed=curtime-call->start_time; ms_message("incoming call ringing for %i seconds",elapsed); @@ -1996,7 +1996,6 @@ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddr **/ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params) { - int err=0; const char *route=NULL; const char *from=NULL; LinphoneProxyConfig *proxy=NULL; @@ -2049,7 +2048,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const lc->current_call=call; linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call"); if (dest_proxy!=NULL || lc->sip_conf.ping_with_options==FALSE){ - err=linphone_core_start_invite(lc,call,dest_proxy); + linphone_core_start_invite(lc,call,dest_proxy); }else{ /*defer the start of the call after the OPTIONS ping*/ call->ping_op=sal_op_new(lc->sal); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index a4a062dca..fbbf9ce18 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -269,10 +269,6 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){ } static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ - const char *id_str; - - if (obj->reg_identity!=NULL) id_str=obj->reg_identity; - else id_str=linphone_core_get_primary_contact(obj->lc); if (obj->reg_sendregister){ char *contact; if (obj->op) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 869a7d8bb..65c60afdd 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -561,19 +561,18 @@ int sal_call(SalOp *h, const char *from, const char *to){ int sal_call_notify_ringing(SalOp *h, bool_t early_media){ osip_message_t *msg; - int err; /*if early media send also 180 and 183 */ if (early_media && h->sdp_answer){ msg=NULL; eXosip_lock(); - err=eXosip_call_build_answer(h->tid,180,&msg); + eXosip_call_build_answer(h->tid,180,&msg); if (msg){ set_sdp(msg,h->sdp_answer); eXosip_call_send_answer(h->tid,180,msg); } msg=NULL; - err=eXosip_call_build_answer(h->tid,183,&msg); + eXosip_call_build_answer(h->tid,183,&msg); if (msg){ set_sdp(msg,h->sdp_answer); eXosip_call_send_answer(h->tid,183,msg); diff --git a/gtk/friendlist.c b/gtk/friendlist.c index f19307606..d1b116272 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -70,7 +70,7 @@ static GdkPixbuf *create_status_picture(LinphoneOnlineStatus ss){ void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid, const gchar *url, const gchar *status, const gchar *img){ GtkTreeIter iter; LinphoneFriend *tmp=0; - gboolean found=FALSE; + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); if (gtk_tree_model_get_iter_first(model,&iter)) { do{ @@ -81,10 +81,9 @@ void linphone_gtk_set_friend_status(GtkWidget *friendlist , LinphoneFriend * fid gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_STATUS,status,-1); pixbuf = create_pixbuf(img); if (pixbuf) - { - gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); - } - found=TRUE; + { + gtk_list_store_set(GTK_LIST_STORE(model),&iter,FRIEND_PRESENCE_IMG, pixbuf,-1); + } } }while(gtk_tree_model_iter_next(model,&iter)); } diff --git a/oRTP b/oRTP index b0c5530be..eb4f54377 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit b0c5530bee255033f09011e5aab6d036e00520dc +Subproject commit eb4f54377e2560a76a05f62a22c961edbce8f4c2 From 840856ca5545dd3e2a18a25db32ce3c00605803d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 31 May 2011 13:14:28 +0200 Subject: [PATCH 04/51] fix divide by zero in oRTP --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index eb4f54377..7b39874da 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit eb4f54377e2560a76a05f62a22c961edbce8f4c2 +Subproject commit 7b39874dae3c514901d40cd62d648ab2f849fdff From c097b9ab6319e2a7ef758032c0ed6d41e009bedb Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 1 Jun 2011 12:22:37 +0200 Subject: [PATCH 05/51] Android video: rename put_image class. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3c348bc98..52b468e36 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3c348bc98e990f0819b972a8b04d80da2d6d0d77 +Subproject commit 52b468e361ebaa7105bc005a606411e9aeb8e8ad From 327e154dba1451447d00a977f408077215524486 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 2 Jun 2011 11:47:17 +0200 Subject: [PATCH 06/51] fix memory leaks --- console/linphonec.c | 1 - mediastreamer2 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/console/linphonec.c b/console/linphonec.c index 38cf24f28..5f7abf38b 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -358,7 +358,6 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L case LinphoneCallOutgoingInit: linphonec_call_identify(call); id=(long)linphone_call_get_user_pointer (call); - from=linphone_call_get_remote_address_as_string(call); linphonec_out("Establishing call id to %s, assigned id %i\n", from,id); break; case LinphoneCallUpdatedByRemote: diff --git a/mediastreamer2 b/mediastreamer2 index 3c348bc98..219ac72b1 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3c348bc98e990f0819b972a8b04d80da2d6d0d77 +Subproject commit 219ac72b1747c2fda993e5908461f090822aa135 From 438ebe84a129b5592e96c95b2af9ab281084375c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 3 Jun 2011 09:39:41 +0200 Subject: [PATCH 07/51] print reason for call ended --- console/linphonec.c | 2 +- coreapi/linphonecore.c | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/console/linphonec.c b/console/linphonec.c index 5f7abf38b..40a243607 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -328,7 +328,7 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L long id=(long)linphone_call_get_user_pointer (call); switch(st){ case LinphoneCallEnd: - linphonec_out("Call %i with %s ended.\n", id, from); + linphonec_out("Call %i with %s ended (%s).\n", id, from, linphone_reason_to_string(linphone_call_get_reason(call))); break; case LinphoneCallResuming: linphonec_out("Resuming call %i with %s.\n", id, from); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2b8eb73e6..7504749ea 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4078,7 +4078,7 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l return p; } -const char *linphone_error_to_string(LinphoneReason err){ +const char *linphone_reason_to_string(LinphoneReason err){ switch(err){ case LinphoneReasonNone: return "No error"; @@ -4091,6 +4091,10 @@ const char *linphone_error_to_string(LinphoneReason err){ } return "unknown error"; } + +const char *linphone_error_to_string(LinphoneReason err){ + return linphone_reason_to_string(err); +} /** * Enables signaling keep alive */ From 391091cead70994de0c78fb4b9bc2b82d0cb98e0 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Mon, 6 Jun 2011 09:48:18 +0200 Subject: [PATCH 08/51] disable neon code on Android non neon hardware --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 219ac72b1..64fddb0ac 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 219ac72b1747c2fda993e5908461f090822aa135 +Subproject commit 64fddb0ac8a6a9017f918b43c758247e8bb13e36 From 1d4ccb16fda34334958aade461a6a8fb8f94f745 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 6 Jun 2011 12:13:22 +0200 Subject: [PATCH 09/51] fix small memleak + update ms2 --- coreapi/callbacks.c | 1 + mediastreamer2 | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index bce577773..a101dbc8e 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -147,6 +147,7 @@ static void call_received(SalOp *h){ if (is_duplicate_call(lc,from_addr,to_addr)){ ms_warning("Receiving duplicated call, refusing this one."); sal_call_decline(h,SalReasonBusy,NULL); + sal_op_release(h); linphone_address_destroy(from_addr); linphone_address_destroy(to_addr); return; diff --git a/mediastreamer2 b/mediastreamer2 index 219ac72b1..ef298ba27 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 219ac72b1747c2fda993e5908461f090822aa135 +Subproject commit ef298ba2719c94f2de563deb7a8ef441d45794fc From c959542ff3ed02d2d0ed493ff102d44399539bdd Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 7 Jun 2011 11:32:04 +0200 Subject: [PATCH 10/51] update de translation --- po/de.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/de.po b/po/de.po index 55ce35cdf..d826a1ff9 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: linphone 0.7.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-04-08 22:32+0200\n" -"PO-Revision-Date: 2011-04-10 02:35+0200\n" +"PO-Revision-Date: 2011-05-27 23:45+0200\n" "Last-Translator: Gerhard Stengel \n" "Language-Team: German \n" "Language: \n" @@ -573,7 +573,7 @@ msgstr "Dauer:" #: ../gtk/main.ui.h:33 msgid "Enable self-view" -msgstr "Selbstansicht einschalten" +msgstr "Selbstansicht ein" #: ../gtk/main.ui.h:34 msgid "Enter username, phone number, or full sip address" @@ -1391,7 +1391,7 @@ msgstr "Abmeldung von %s ist erfolgt." #: ../coreapi/callbacks.c:574 msgid "no response timeout" -msgstr "keine Zeitüberschreitung bei der Antwort" +msgstr "Zeitüberschreitung bei der Antwort" #: ../coreapi/callbacks.c:577 #, c-format From 4f2c73c2f2787bff8a02a4d2e3d918fe2392c5e1 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 9 Jun 2011 23:27:29 +0200 Subject: [PATCH 11/51] implement call quality indicator --- coreapi/help/doxygen.dox | 7 +++ coreapi/linphonecall.c | 68 ++++++++++++++++++++---- coreapi/linphonecore.h | 2 + gtk/incall_view.c | 60 ++++++++++++++++++++- gtk/main.c | 10 ---- gtk/main.ui | 111 +++++++++++++++------------------------ mediastreamer2 | 2 +- oRTP | 2 +- 8 files changed, 170 insertions(+), 92 deletions(-) diff --git a/coreapi/help/doxygen.dox b/coreapi/help/doxygen.dox index 99293c65b..7d0a82849 100644 --- a/coreapi/help/doxygen.dox +++ b/coreapi/help/doxygen.dox @@ -43,6 +43,13 @@ * **/ +/** + * @defgroup call_misc Obtaining information about a running call: sound volumes, quality indicators + * + * When a call is running, it is possible to retrieve in real time current measured volumes and quality indicator. + * +**/ + /** * @defgroup media_parameters Controlling media parameters **/ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index ab521aa7f..fdcca58d1 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -585,6 +585,17 @@ void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int cp->audio_bw=bandwidth; } +#ifdef VIDEO_ENABLED +/** + * Request remote side to send us a Video Fast Update. +**/ +void linphone_call_send_vfu_request(LinphoneCall *call) +{ + if (LinphoneCallStreamsRunning == linphone_call_get_state(call)) + sal_call_send_vfu_request(call->op); +} +#endif + /** * **/ @@ -1040,16 +1051,7 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ } } -#ifdef VIDEO_ENABLED -/** - * Request remote side to send us VFU. -**/ -void linphone_call_send_vfu_request(LinphoneCall *call) -{ - if (LinphoneCallStreamsRunning == linphone_call_get_state(call)) - sal_call_send_vfu_request(call->op); -} -#endif + void linphone_call_enable_echo_cancellation(LinphoneCall *call, bool_t enable) { if (call!=NULL && call->audiostream!=NULL && call->audiostream->ec){ @@ -1089,6 +1091,11 @@ bool_t linphone_call_echo_limiter_enabled(const LinphoneCall *call){ } } +/** + * @addtogroup call_misc + * @{ +**/ + /** * Returns the measured sound volume played locally (received from remote) * It is expressed in dbm0. @@ -1119,6 +1126,45 @@ float linphone_call_get_record_volume(LinphoneCall *call){ return LINPHONE_VOLUME_DB_LOWEST; } +/** + * Obtain real-time quality rating of the call + * + * Based on local RTP statistics and RTCP feedback, a quality rating is computed and updated + * during all the duration of the call. This function returns its value at the time of the function call. + * It is expected that the rating is updated at least every 5 seconds or so. + * The rating is a floating point number comprised between 0 and 5. + * + * 4-5 = good quality
+ * 3-4 = average quality
+ * 2-3 = poor quality
+ * 1-2 = very poor quality
+ * 0-1 = can't be worse, mostly unusable
+ * + * @returns The function returns -1 if no quality measurement is available, for example if no + * active audio stream exist. Otherwise it returns the quality rating. +**/ +float linphone_call_get_current_quality(LinphoneCall *call){ + if (call->audiostream){ + return audio_stream_get_quality_rating(call->audiostream); + } + return -1; +} + +/** + * Returns call quality averaged over all the duration of the call. + * + * See linphone_call_get_current_quality() for more details about quality measurement. +**/ +float linphone_call_get_average_quality(LinphoneCall *call){ + if (call->audiostream){ + return audio_stream_get_average_quality_rating(call->audiostream); + } + return -1; +} + +/** + * @} +**/ static void display_bandwidth(RtpSession *as, RtpSession *vs){ ms_message("bandwidth usage: audio=[d=%.1f,u=%.1f] video=[d=%.1f,u=%.1f] kbit/sec", @@ -1171,6 +1217,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse if (call->videostream!=NULL) video_stream_iterate(call->videostream); #endif + if (call->audiostream!=NULL) + audio_stream_iterate(call->audiostream); if (one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 ) disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout); if (disconnected) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 50fdb96d8..cd57b926d 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -255,6 +255,8 @@ LinphoneReason linphone_call_get_reason(const LinphoneCall *call); const char *linphone_call_get_remote_user_agent(LinphoneCall *call); float linphone_call_get_play_volume(LinphoneCall *call); float linphone_call_get_record_volume(LinphoneCall *call); +float linphone_call_get_current_quality(LinphoneCall *call); +float linphone_call_get_average_quality(LinphoneCall *call); void *linphone_call_get_user_pointer(LinphoneCall *call); void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); /** diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 96f672cfc..919adaa3c 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -205,7 +205,6 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus gtk_label_set_markup(GTK_LABEL(status),_("Incoming call")); gtk_widget_show_all(linphone_gtk_get_widget(callview,"answer_decline_panel")); - gtk_widget_hide(linphone_gtk_get_widget(callview,"duration_frame")); gtk_widget_hide(linphone_gtk_get_widget(callview,"mute_pause_buttons")); display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); @@ -228,6 +227,57 @@ void linphone_gtk_in_call_view_set_incoming(LinphoneCall *call, bool_t with_paus }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG); } +static void rating_to_color(float rating, GdkColor *color){ + const char *colorname="grey"; + if (rating>=4.0) + colorname="green"; + else if (rating>=3.0) + colorname="white"; + else if (rating>=2.0) + colorname="yellow"; + else if (rating>=1.0) + colorname="orange"; + else if (rating>=0) + colorname="red"; + if (!gdk_color_parse(colorname,color)){ + g_warning("Fail to parse color %s",colorname); + } +} + +static const char *rating_to_text(float rating){ + if (rating>=4.0) + return _("good"); + if (rating>=3.0) + return _("average"); + if (rating>=2.0) + return _("poor"); + if (rating>=1.0) + return _("very poor"); + if (rating>=0) + return _("too bad"); + return _("unavailable"); +} + +static gboolean linphone_gtk_in_call_view_refresh(LinphoneCall *call){ + GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); + GtkWidget *qi=linphone_gtk_get_widget(callview,"quality_indicator"); + float rating=linphone_call_get_current_quality(call); + GdkColor color; + gchar tmp[50]; + linphone_gtk_in_call_view_update_duration(call); + if (rating>=0){ + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(qi),rating/5.0); + snprintf(tmp,sizeof(tmp),"%.1f (%s)",rating,rating_to_text(rating)); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(qi),tmp); + }else{ + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(qi),0); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(qi),_("unavailable")); + } + rating_to_color(rating,&color); + gtk_widget_modify_bg(qi,GTK_STATE_NORMAL,&color); + return TRUE; +} + void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call); GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); @@ -235,10 +285,10 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ GtkWidget *duration=linphone_gtk_get_widget(callview,"in_call_duration"); GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("incall_anim.gif"); + guint taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid")); display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); - gtk_widget_show(linphone_gtk_get_widget(callview,"duration_frame")); gtk_widget_show(linphone_gtk_get_widget(callview,"mute_pause_buttons")); gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_label_set_markup(GTK_LABEL(status),_("In call")); @@ -250,6 +300,10 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ }else gtk_image_set_from_stock(GTK_IMAGE(animation),GTK_STOCK_EXECUTE,GTK_ICON_SIZE_DIALOG); linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),TRUE); + if (taskid==0){ + taskid=g_timeout_add(250,(GSourceFunc)linphone_gtk_in_call_view_refresh,call); + g_object_set_data(G_OBJECT(callview),"taskid",GINT_TO_POINTER(taskid)); + } } void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){ @@ -283,6 +337,7 @@ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_m GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status"); GtkWidget *animation=linphone_gtk_get_widget(callview,"in_call_animation"); GdkPixbuf *pbuf=create_pixbuf(linphone_gtk_get_ui_config("stop_call_icon","stopcall-red.png")); + guint taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid")); if (error_msg==NULL) gtk_label_set_markup(GTK_LABEL(status),_("Call ended.")); @@ -299,6 +354,7 @@ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_m linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),FALSE); linphone_gtk_enable_hold_button(call,FALSE,TRUE); + if (taskid!=0) g_source_remove(taskid); g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,call); } diff --git a/gtk/main.c b/gtk/main.c index b47296f27..6968466d8 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -632,15 +632,6 @@ void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){ update_video_title(); } -static gboolean in_call_timer(){ - LinphoneCall *call=linphone_core_get_current_call(linphone_gtk_get_core()); - if (call){ - linphone_gtk_in_call_view_update_duration(call); - return TRUE; - } - return FALSE; -} - static bool_t all_other_calls_paused(LinphoneCall *refcall, const MSList *calls){ for(;calls!=NULL;calls=calls->next){ LinphoneCall *call=(LinphoneCall*)calls->data; @@ -961,7 +952,6 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"main_mute")), TRUE); - g_timeout_add(250,(GSourceFunc)in_call_timer,NULL); break; case LinphoneCallError: linphone_gtk_in_call_view_terminate (call,msg); diff --git a/gtk/main.ui b/gtk/main.ui index aaa4ae4a4..c24591a91 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1,4 +1,4 @@ - + @@ -62,7 +62,6 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - vertical True @@ -234,7 +233,6 @@ True - vertical True @@ -285,7 +283,7 @@ True True Enter username, phone number, or full sip address - + @@ -337,7 +335,6 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - vertical True @@ -345,7 +342,6 @@ True - vertical True @@ -361,7 +357,6 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - vertical True @@ -381,7 +376,7 @@ True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + @@ -459,10 +454,10 @@ True True - + + - @@ -702,7 +697,6 @@ True - vertical True @@ -1089,7 +1083,6 @@ True - vertical True @@ -1144,7 +1137,7 @@ True True - + 1 @@ -1156,7 +1149,7 @@ True True False - + 1 @@ -1334,7 +1327,6 @@ True - vertical True @@ -1346,22 +1338,10 @@ - + True - 0 - - - True - label - center - - - - - True - True - - + label + center 1 @@ -1405,39 +1385,6 @@ 2 - - - True - 0 - - - True - vertical - - - True - Duration - center - - - 0 - - - - - - - True - Duration: - True - - - - - False - 3 - - True @@ -1474,7 +1421,7 @@ False False - 4 + 3 @@ -1482,11 +1429,39 @@ - + True - In call - True - center + True + + + True + In call + True + center + + + 0 + + + + + True + Duration + center + + + 1 + + + + + True + Call quality rating + + + 2 + + diff --git a/mediastreamer2 b/mediastreamer2 index ef298ba27..3c6e9bf14 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ef298ba2719c94f2de563deb7a8ef441d45794fc +Subproject commit 3c6e9bf14efefa4ddd078d7b24ce46b5177da3c7 diff --git a/oRTP b/oRTP index 7b39874da..6e9ac1d1f 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 7b39874dae3c514901d40cd62d648ab2f849fdff +Subproject commit 6e9ac1d1f7c60f60bd67656c92ae801c61f41b27 From fdf9d2722c426ba39d95fe4f45cfc58bf580ef3e Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 10 Jun 2011 11:56:06 +0200 Subject: [PATCH 12/51] update msstreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3c6e9bf14..79cbc5277 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3c6e9bf14efefa4ddd078d7b24ce46b5177da3c7 +Subproject commit 79cbc5277d3fae8a70ae42a4e958042484ca2725 From ddff1d846004ac4373d00458cd10f6c2dbabedc8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 10 Jun 2011 16:01:08 +0200 Subject: [PATCH 13/51] display average quality in call logs --- coreapi/linphonecall.c | 1 + coreapi/linphonecore.c | 2 ++ coreapi/linphonecore.h | 1 + coreapi/lpconfig.c | 9 +++++++-- coreapi/lpconfig.h | 6 ++++++ gtk/calllogs.c | 10 ++++++++-- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index fdcca58d1..8649c4c45 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1015,6 +1015,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){ audio_stream_get_local_rtp_stats (st,&log->local_stats); + log->quality=audio_stream_get_average_quality_rating(st); } void linphone_call_stop_media_streams(LinphoneCall *call){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 7504749ea..d179d8104 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -124,6 +124,7 @@ void call_logs_write_to_config_file(LinphoneCore *lc){ lp_config_set_string(cfg,logsection,"start_date",cl->start_date); 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); } for(;imax_call_logs;++i){ snprintf(logsection,sizeof(logsection),"call_log_%i",i); @@ -151,6 +152,7 @@ static void call_logs_read_from_config_file(LinphoneCore *lc){ cl->duration=lp_config_get_int(cfg,logsection,"duration",0); 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); lc->call_logs=ms_list_append(lc->call_logs,cl); }else break; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index cd57b926d..02c4c607a 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -152,6 +152,7 @@ typedef struct _LinphoneCallLog{ void *user_pointer; rtp_stats_t local_stats; rtp_stats_t remote_stats; + float quality; struct _LinphoneCore *lc; } LinphoneCallLog; diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index ce093cbaf..0de019e57 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -307,9 +307,14 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value){ char tmp[30]; - snprintf(tmp,30,"%i",value); + snprintf(tmp,sizeof(tmp),"%i",value); + lp_config_set_string(lpconfig,section,key,tmp); +} + +void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key, float value){ + char tmp[30]; + snprintf(tmp,sizeof(tmp),"%f",value); lp_config_set_string(lpconfig,section,key,tmp); - lpconfig->modified++; } void lp_item_write(LpItem *item, FILE *file){ diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h index bb731acbc..ed7a66b1e 100644 --- a/coreapi/lpconfig.h +++ b/coreapi/lpconfig.h @@ -86,6 +86,12 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke * @ingroup misc **/ void lp_config_set_int(LpConfig *lpconfig,const char *section, const char *key, int value); +/** + * Sets a float config item + * + * @ingroup misc +**/ +void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key, float value); /** * Writes the config file to disk. * diff --git a/gtk/calllogs.c b/gtk/calllogs.c index c196c2c41..f336992d7 100644 --- a/gtk/calllogs.c +++ b/gtk/calllogs.c @@ -40,14 +40,20 @@ void linphone_gtk_call_log_update(GtkWidget *w){ char *addr= linphone_address_as_string_uri_only (la); const char *display; gchar *logtxt; + gchar quality[20]; + display=linphone_address_get_display_name (la); if (display==NULL){ display=linphone_address_get_username (la); if (display==NULL) display=linphone_address_get_domain (la); } - logtxt=g_markup_printf_escaped("%s\t%s\n" - "%s\t%i minutes %i seconds",display, addr, cl->start_date, + if (cl->quality!=-1){ + snprintf(quality,sizeof(quality),"%.1f",cl->quality); + } + logtxt=g_markup_printf_escaped("%s\t%s\tQuality: %s\n" + "%s\t%i minutes %i seconds\t",display, addr, cl->quality!=-1 ? quality : _("n/a"), + cl->start_date, cl->duration/60,cl->duration%60); gtk_list_store_append (store,&iter); gtk_list_store_set (store,&iter, From 96f5278f71a477eb67ad2f986d7666554986b0d7 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 10 Jun 2011 19:04:09 +0200 Subject: [PATCH 14/51] add jni glue and java interface for call quality indicator --- coreapi/linphonecore_jni.cc | 12 ++++++++++ .../org/linphone/core/LinphoneCall.java | 24 +++++++++++++++++++ mediastreamer2 | 2 +- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 4e201c845..2492e8f61 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1023,6 +1023,18 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getReplacedCall( JNIEnv return (jlong)linphone_call_get_replaced_call((LinphoneCall*)ptr); } +extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getCurrentQuality( JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return (jfloat)linphone_call_get_current_quality((LinphoneCall*)ptr); +} + +extern "C" jfloat Java_org_linphone_core_LinphoneCallImpl_getAverageQuality( JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return (jfloat)linphone_call_get_average_quality((LinphoneCall*)ptr); +} + //LinphoneFriend extern "C" long Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index 9f029b053..e0f7cde34 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -190,4 +190,28 @@ public interface LinphoneCall { * @return call duration computed from media start */ int getDuration(); + /** + * Obtain real-time quality rating of the call + * + * Based on local RTP statistics and RTCP feedback, a quality rating is computed and updated + * during all the duration of the call. This function returns its value at the time of the function call. + * It is expected that the rating is updated at least every 5 seconds or so. + * The rating is a floating point number comprised between 0 and 5. + * + * 4-5 = good quality
+ * 3-4 = average quality
+ * 2-3 = poor quality
+ * 1-2 = very poor quality
+ * 0-1 = can't be worse, mostly unusable
+ * + * @returns The function returns -1 if no quality measurement is available, for example if no + * active audio stream exist. Otherwise it returns the quality rating. + */ + float getCurrentQuality(); + /** + * Returns call quality averaged over all the duration of the call. + * + * See getCurrentQuality() for more details about quality measurement. + */ + float getAverageQuality(); } diff --git a/mediastreamer2 b/mediastreamer2 index 79cbc5277..13dd93a64 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 79cbc5277d3fae8a70ae42a4e958042484ca2725 +Subproject commit 13dd93a64be54e9b015d38e6cd72695b3dff5e19 From be90cd896ecf81fe6f57f5baa8129ca0a33b4731 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 14 Jun 2011 13:03:16 +0200 Subject: [PATCH 15/51] support for adaptive rate control --- coreapi/linphonecall.c | 16 ++++++++++++---- coreapi/linphonecore.c | 20 ++++++++++++++++++++ coreapi/linphonecore.h | 7 +++++-- mediastreamer2 | 2 +- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 8649c4c45..2aaad1444 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -669,6 +669,7 @@ void linphone_call_init_media_streams(LinphoneCall *call){ int enabled=lp_config_get_int(lc->config,"sound","noisegate",0); audio_stream_enable_noise_gate(audiostream,enabled); } + if (lc->a_rtp) rtp_session_set_transports(audiostream->session,lc->a_rtp,lc->a_rtcp); @@ -853,6 +854,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc, SalProtoRtpAvp,SalVideo); #endif + bool_t use_arc=linphone_core_adaptive_rate_control_enabled(lc); if(call->audiostream == NULL) { @@ -876,7 +878,7 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut const char *playfile=lc->play_file; const char *recfile=lc->rec_file; call->audio_profile=make_profile(call,call->resultdesc,stream,&used_pt); - bool_t use_ec; + bool_t use_ec,use_arc_audio=use_arc; if (used_pt!=-1){ if (playcard==NULL) { @@ -907,11 +909,17 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut playcard=NULL; } use_ec=captcard==NULL ? FALSE : linphone_core_echo_cancellation_enabled(lc); -#if defined(VIDEO_ENABLED) && defined(ANDROID) - /*On android we have to disable the echo canceller to preserve CPU for video codecs */ - if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL) +#if defined(VIDEO_ENABLED) + if (vstream && vstream->dir!=SalStreamInactive && vstream->payloads!=NULL){ + /*when video is used, do not make adaptive rate control on audio, it is stupid.*/ + use_arc_audio=FALSE; + #if defined(ANDROID) + /*On android we have to disable the echo canceller to preserve CPU for video codecs */ use_ec=FALSE; + #endif + } #endif + audio_stream_enable_adaptive_bitrate_control(call->audiostream,use_arc_audio); audio_stream_start_full( call->audiostream, call->audio_profile, diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d179d8104..7f0e8c727 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -782,6 +782,26 @@ static void autoreplier_config_init(LinphoneCore *lc) } */ +/** + * Enable adaptive rate control (experimental feature, audio-only). + * + * Adaptive rate control consists in using RTCP feedback provided information to dynamically + * control the output bitrate of the encoders, so that we can adapt to the network conditions and + * available bandwidth. +**/ +void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled){ + lp_config_set_int(lc->config,"net","adaptive_rate_control",(int)enabled); +} + +/** + * Returns whether adaptive rate control is enabled. + * + * See linphone_core_enable_adaptive_rate_control(). +**/ +bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){ + return lp_config_get_int(lc->config,"net","adaptive_rate_control",FALSE); +} + /** * Sets maximum available download bandwidth * diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 02c4c607a..8a298332f 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -705,14 +705,17 @@ void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw); int linphone_core_get_download_bandwidth(const LinphoneCore *lc); int linphone_core_get_upload_bandwidth(const LinphoneCore *lc); + +void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled); +bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc); /** - * set audio packetization time linphone expect to received from peer + * set audio packetization time linphone expect to receive from peer * @ingroup media_parameters * */ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime); /** - * get audio packetization time linphone expect to received from peer, 0 means unspecified + * get audio packetization time linphone expect to receive from peer, 0 means unspecified * @ingroup media_parameters */ int linphone_core_get_download_ptime(LinphoneCore *lc); diff --git a/mediastreamer2 b/mediastreamer2 index 79cbc5277..fd74240c2 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 79cbc5277d3fae8a70ae42a4e958042484ca2725 +Subproject commit fd74240c297e33c7e96d14dc5f7ed5d3dbdb8dc0 From 6e8cf5e4a3f54535ee951a748420aa5aac3f64cd Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 15 Jun 2011 13:01:01 +0200 Subject: [PATCH 16/51] fix contact update after registration in case of TCP --- coreapi/linphonecore.c | 4 +- coreapi/proxy.c | 2 +- coreapi/sal.c | 21 ++++- coreapi/sal.h | 20 +++-- coreapi/sal_eXosip2.c | 179 ++++++++++++++++++++++++++++------------- 5 files changed, 159 insertions(+), 67 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d179d8104..aa88a263e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1375,13 +1375,13 @@ static int apply_transports(LinphoneCore *lc){ sal_unlisten_ports (sal); if (tr->udp_port>0){ - if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportDatagram,FALSE)!=0){ + if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){ transport_error(lc,"UDP",tr->udp_port); return -1; } } if (tr->tcp_port>0){ - if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportStream,FALSE)!=0){ + if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){ transport_error(lc,"TCP",tr->tcp_port); } } diff --git a/coreapi/proxy.c b/coreapi/proxy.c index fbbf9ce18..ff13f839e 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -259,7 +259,7 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){ linphone_core_get_sip_transports(obj->lc,&tr); if (tr.udp_port <= 0 && tr.tcp_port>0) { - sal_address_add_param(contact,"transport","tcp"); + sal_address_set_param(contact,"transport","TCP"); } ret=linphone_address_as_string(contact); linphone_address_destroy(contact); diff --git a/coreapi/sal.c b/coreapi/sal.c index b25f39451..1af6d000b 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -24,7 +24,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. **/ #include "sal.h" - +const char* sal_transport_to_string(SalTransport transport) { + switch (transport) { + case SalTransportUDP:return "UDP"; + case SalTransportTCP: return "TCP"; + case SalTransportTLS:return "TLS"; + case SalTransportDTLS:return "DTLS"; + default: { + ms_fatal("Unexpected transport [%i]",transport); + } + + } +} +SalTransport sal_transport_parse(const char* param) { + if (strcasecmp("UDP",param)==0) return SalTransportUDP; + if (strcasecmp("TCP",param)==0) return SalTransportTCP; + if (strcasecmp("TLS",param)==0) return SalTransportTLS; + if (strcasecmp("DTLS",param)==0) return SalTransportDTLS; + ms_error("Unkown transport type[%s], returning UDP", param); + return SalTransportUDP; +} SalMediaDescription *sal_media_description_new(){ SalMediaDescription *md=ms_new0(SalMediaDescription,1); md->refcount=1; diff --git a/coreapi/sal.h b/coreapi/sal.h index a89b862c0..af1ddc367 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -40,6 +40,15 @@ struct SalAddress; typedef struct SalAddress SalAddress; +typedef enum { + SalTransportUDP, /*UDP*/ + SalTransportTCP, /*TCP*/ + SalTransportTLS, /*TLS*/ + SalTransportDTLS /*DTLS*/ +}SalTransport; + +const char* sal_transport_to_string(SalTransport transport); +SalTransport sal_transport_parse(const char*); /* Address manipulation API*/ SalAddress * sal_address_new(const char *uri); SalAddress * sal_address_clone(const SalAddress *addr); @@ -49,7 +58,8 @@ char *sal_address_get_display_name_unquoted(const SalAddress *addr); const char *sal_address_get_username(const SalAddress *addr); const char *sal_address_get_domain(const SalAddress *addr); const char * sal_address_get_port(const SalAddress *addr); -int sal_address_get_port_int(const SalAddress *uri); +int sal_address_get_port_int(const SalAddress *addr); +SalTransport sal_address_get_transport(const SalAddress* addr); void sal_address_set_display_name(SalAddress *addr, const char *display_name); void sal_address_set_username(SalAddress *addr, const char *username); @@ -60,8 +70,8 @@ void sal_address_clean(SalAddress *addr); char *sal_address_as_string(const SalAddress *u); char *sal_address_as_string_uri_only(const SalAddress *u); void sal_address_destroy(SalAddress *u); -void sal_address_add_param(SalAddress *u,const char* name,const char* value); - +void sal_address_set_param(SalAddress *u,const char* name,const char* value); +void sal_address_set_transport(SalAddress* addr,SalTransport transport); Sal * sal_init(); @@ -69,10 +79,6 @@ void sal_uninit(Sal* sal); void sal_set_user_pointer(Sal *sal, void *user_data); void *sal_get_user_pointer(const Sal *sal); -typedef enum { - SalTransportDatagram, - SalTransportStream -}SalTransport; typedef enum { SalAudio, diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 65c60afdd..c62f828fb 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -32,6 +32,10 @@ static bool_t call_failure(Sal *sal, eXosip_event_t *ev); static void text_received(Sal *sal, eXosip_event_t *ev); +static void masquerade_via(osip_message_t *msg, const char *ip, const char *port); +static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer); +static void update_contact_from_response(SalOp *op, osip_message_t *response); + void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){ void *data; while(!osip_list_eol(l,0)) { @@ -351,11 +355,11 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i int keepalive = ctx->keepalive_period; switch (tr) { - case SalTransportDatagram: + case SalTransportUDP: proto=IPPROTO_UDP; eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive); break; - case SalTransportStream: + case SalTransportTCP: proto= IPPROTO_TCP; keepalive=-1; eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); @@ -424,7 +428,8 @@ void sal_use_rport(Sal *ctx, bool_t use_rports){ void sal_use_101(Sal *ctx, bool_t use_101){ ctx->use_101=use_101; } -static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){ + +static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ osip_via_t *via=NULL; osip_generic_param_t *param=NULL; const char *rport=NULL; @@ -434,10 +439,7 @@ static int extract_received_rport(osip_message_t *msg, const char **received, in osip_message_get_via(msg,0,&via); if (!via) return -1; - /* it is useless to do that with tcp since client socket might have a different port - than the server socket. - */ - if (strcasecmp(via->protocol,"tcp")==0) return -1; + *transport = sal_transport_parse(via->protocol); if (via->port && via->port[0]!='\0') *rportval=atoi(via->port); @@ -800,9 +802,13 @@ int sal_call_terminate(SalOp *h){ } void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ - if (h->pending_auth){ + if (h->pending_auth){ push_auth_to_exosip(info); eXosip_lock(); + /*FIXME exosip does not take into account this update register message*/ + if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) { + update_contact_from_response(h,h->pending_auth->response); + }; eXosip_default_action(h->pending_auth); eXosip_unlock(); ms_message("eXosip_default_action() done"); @@ -826,7 +832,8 @@ static void set_network_origin(SalOp *op, osip_message_t *req){ const char *received=NULL; int rport=5060; char origin[64]; - if (extract_received_rport(req,&received,&rport)!=0){ + SalTransport transport; + if (extract_received_rport(req,&received,&rport,&transport)!=0){ osip_via_t *via=NULL; char *tmp; osip_message_get_via(req,0,&via); @@ -834,7 +841,11 @@ static void set_network_origin(SalOp *op, osip_message_t *req){ tmp=osip_via_get_port(via); if (tmp) rport=atoi(tmp); } - snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport); + if (transport != SalTransportUDP) { + snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport); + } else { + snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport)); + } __sal_op_set_network_origin(op,origin); } @@ -992,7 +1003,8 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){ static void update_contact_from_response(SalOp *op, osip_message_t *response){ const char *received; int rport; - if (extract_received_rport(response,&received,&rport)==0){ + SalTransport transport; + if (extract_received_rport(response,&received,&rport,&transport)==0){ const char *contact=sal_op_get_contact(op); if (!contact){ /*no contact given yet, use from instead*/ @@ -1003,8 +1015,9 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){ char *tmp; sal_address_set_domain(addr,received); sal_address_set_port_int(addr,rport); + sal_address_set_transport(addr,transport); tmp=sal_address_as_string(addr); - ms_message("Contact address updated to %s for this dialog",tmp); + ms_message("Contact address updated to %s",tmp); sal_op_set_contact(op,tmp); sal_address_destroy(addr); ms_free(tmp); @@ -1601,39 +1614,22 @@ static void masquerade_via(osip_message_t *msg, const char *ip, const char *port } } -static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){ - osip_message_t *msg; - const char *received; - int rport; - osip_contact_t *ctt=NULL; - char *tmp; - char port[20]; - SalAddress *addr; - Sal *sal=op->base.root; - if (sal->double_reg==FALSE) return FALSE; - - if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE; - osip_message_get_contact(orig_request,0,&ctt); - if (strcmp(ctt->url->host,received)==0){ - /*ip address matches, check ports*/ - const char *contact_port=ctt->url->port; - if (contact_port==NULL || contact_port[0]=='\0') - contact_port="5060"; - if (atoi(contact_port)==rport){ - ms_message("Register has up to date contact, doing nothing."); - return FALSE; - }else ms_message("ports do not match, need to update the register (%s <> %i)", contact_port,rport); - } +static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer) { + osip_contact_t *ctt=NULL; + const char *received; + int rport; + SalTransport transport; + char port[20]; + + if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; eXosip_lock(); - msg=NULL; - eXosip_register_build_register(op->rid,op->expires,&msg); - if (msg==NULL){ - eXosip_unlock(); - ms_warning("Fail to create a contact updated register."); - return FALSE; - } - osip_message_get_contact(msg,0,&ctt); + osip_message_get_contact(request,0,&ctt); + if (ctt == NULL) { + /*nothing to update*/ + eXosip_unlock(); + return FALSE; + } if (ctt->url->host!=NULL){ osip_free(ctt->url->host); } @@ -1643,19 +1639,69 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori } snprintf(port,sizeof(port),"%i",rport); ctt->url->port=osip_strdup(port); - if (op->masquerade_via) masquerade_via(msg,received,port); - eXosip_register_send_register(op->rid,msg); + if (op->masquerade_via) masquerade_via(request,received,port); + + if (transport != SalTransportUDP) { + sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport)); + + } eXosip_unlock(); + return TRUE; + +} + +static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){ + osip_contact_t *ctt=NULL; + SalAddress* ori_contact_address=NULL; + const char *received; + int rport; + SalTransport transport; + char* tmp; + osip_message_t *msg=NULL; + Sal* sal=op->base.root; + + if (sal->double_reg==FALSE ) return FALSE; + + if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; + osip_message_get_contact(orig_request,0,&ctt); osip_contact_to_str(ctt,&tmp); - addr=sal_address_new(tmp); - osip_free(tmp); - sal_address_clean(addr); - tmp=sal_address_as_string(addr); - sal_op_set_contact(op,tmp); - sal_address_destroy(addr); - ms_message("Resending new register with updated contact %s",tmp); - ms_free(tmp); - return TRUE; + ori_contact_address = sal_address_new((const char*)tmp); + osip_free(tmp); + /*check if contact is up to date*/ + if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0 + && sal_address_get_port_int(ori_contact_address) == rport + && sal_address_get_transport(ori_contact_address) == transport) { + ms_message("Register has up to date contact, doing nothing."); + return FALSE; + } else ms_message("contact do not match, need to update the register (%s with %s:%i;transport=%s)" + ,tmp + ,received + ,rport + ,sal_transport_to_string(transport)); + + sal_address_destroy(ori_contact_address); + + if (transport == SalTransportUDP) { + eXosip_lock(); + eXosip_register_build_register(op->rid,op->expires,&msg); + if (msg==NULL){ + eXosip_unlock(); + ms_warning("Fail to create a contact updated register."); + return FALSE; + } + if (fix_message_contact(op,msg,last_answer)) { + eXosip_register_send_register(op->rid,msg); + ms_message("Resending new register with updated contact"); + return TRUE; + } else { + ms_warning("Fail to send updated register."); + eXosip_unlock(); + return FALSE; + } + } + + update_contact_from_response(op,last_answer); + return FALSE; } static void registration_success(Sal *sal, eXosip_event_t *ev){ @@ -2081,8 +2127,16 @@ char *sal_address_as_string_uri_only(const SalAddress *u){ osip_free(tmp); return ret; } -void sal_address_add_param(SalAddress *u,const char* name,const char* value) { - osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value)); +void sal_address_set_param(SalAddress *u,const char* name,const char* value) { + osip_uri_param_t *param=NULL; + osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m); + if (param == NULL){ + osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value)); + } else { + osip_free(param->gvalue); + param->gvalue=osip_strdup(value); + } + } void sal_address_destroy(SalAddress *u){ @@ -2110,6 +2164,19 @@ int sal_address_get_port_int(const SalAddress *uri) { return 5060; } } +SalTransport sal_address_get_transport(const SalAddress* addr) { + const osip_from_t *u=(const osip_from_t*)addr; + osip_uri_param_t *transport_param=NULL; + osip_uri_uparam_get_byname(u->url,"transport",&transport_param); + if (transport_param == NULL){ + return SalTransportUDP; + } else { + return sal_transport_parse(transport_param->gvalue); + } +} +void sal_address_set_transport(SalAddress* addr,SalTransport transport) { + sal_address_set_param(addr, "transport", sal_transport_to_string(transport)); +} /* sends a reinvite. Local media description may have changed by application since call establishment*/ int sal_call_update(SalOp *h, const char *subject){ From e545c638329025423c6bd7873f0af159be662750 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 15 Jun 2011 13:34:04 +0200 Subject: [PATCH 17/51] fix compilation issue --- coreapi/sal.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/sal.c b/coreapi/sal.c index 1af6d000b..92b82d52c 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -32,6 +32,7 @@ const char* sal_transport_to_string(SalTransport transport) { case SalTransportDTLS:return "DTLS"; default: { ms_fatal("Unexpected transport [%i]",transport); + return NULL; } } From 451c2ae3a3ba4cbb7718c7706a94646da0d4083d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 16 Jun 2011 14:54:38 +0200 Subject: [PATCH 18/51] add apis to control upload ptime --- coreapi/linphonecall.c | 7 ++++++- coreapi/linphonecore.c | 26 ++++++++++++++++++++++++-- mediastreamer2 | 2 +- oRTP | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 2aaad1444..36a41186e 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -793,6 +793,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m bool_t first=TRUE; int remote_bw=0; LinphoneCore *lc=call->core; + int up_ptime=0; *used_pt=-1; for(elem=desc->payloads;elem!=NULL;elem=elem->next){ @@ -802,6 +803,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m if (first) { if (desc->type==SalAudio){ linphone_core_update_allocated_audio_bandwidth_in_call(call,pt); + up_ptime=linphone_core_get_upload_ptime(lc); } *used_pt=payload_type_get_number(pt); first=FALSE; @@ -823,8 +825,11 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m pt->normal_bitrate=-1; } if (desc->ptime>0){ + up_ptime=desc->ptime; + } + if (up_ptime>0){ char tmp[40]; - snprintf(tmp,sizeof(tmp),"ptime=%i",desc->ptime); + snprintf(tmp,sizeof(tmp),"ptime=%i",up_ptime); payload_type_append_send_fmtp(pt,tmp); } number=payload_type_get_number(pt); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 7f0e8c727..2bbda0f24 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -861,16 +861,38 @@ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){ return lc->net_conf.upload_bw; } /** - * set audio packetization time linphone expect to received from peer + * Set audio packetization time linphone expects to receive from peer */ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) { lc->net_conf.down_ptime=ptime; } -int linphone_core_get_download_ptime(LinphoneCore *lc) { +/** + * Get audio packetization time linphone expects to receive from peer + */ +int linphone_core_get_download_ptime(LinphoneCore *lc) { return lc->net_conf.down_ptime; } +/** + * Set audio packetization time linphone will send (in absence of requirement from peer) + * A value of 0 stands for the current codec default packetization time. + * +**/ +void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){ + lp_config_set_int(lc->config,"rtp","up_ptime",ptime); +} + +/** + * Set audio packetization time linphone will send (in absence of requirement from peer) + * A value of 0 stands for the current codec default packetization time. + * +**/ +int linphone_core_get_upload_ptime(LinphoneCore *lc){ + return lp_config_get_int(lc->config,"rtp","up_ptime",0); +} + + /** * Returns liblinphone's version as a string. diff --git a/mediastreamer2 b/mediastreamer2 index fd74240c2..07d1b02eb 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit fd74240c297e33c7e96d14dc5f7ed5d3dbdb8dc0 +Subproject commit 07d1b02eb57b7fc5cc8e4821c6485df2f138906e diff --git a/oRTP b/oRTP index 6e9ac1d1f..3af8aa68f 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 6e9ac1d1f7c60f60bd67656c92ae801c61f41b27 +Subproject commit 3af8aa68f253d802b674cc1807115e4556c0fafa From 338884fa4d64a59e30697de8fc68b1e84b7ca504 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 16 Jun 2011 15:16:34 +0200 Subject: [PATCH 19/51] fix double locks --- coreapi/sal_eXosip2.c | 148 +++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 73 deletions(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index c62f828fb..42574dc8f 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -804,11 +804,15 @@ int sal_call_terminate(SalOp *h){ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ if (h->pending_auth){ push_auth_to_exosip(info); - eXosip_lock(); + /*FIXME exosip does not take into account this update register message*/ + /* if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) { - update_contact_from_response(h,h->pending_auth->response); + }; + */ + update_contact_from_response(h,h->pending_auth->response); + eXosip_lock(); eXosip_default_action(h->pending_auth); eXosip_unlock(); ms_message("eXosip_default_action() done"); @@ -1003,7 +1007,7 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){ static void update_contact_from_response(SalOp *op, osip_message_t *response){ const char *received; int rport; - SalTransport transport; + SalTransport transport; if (extract_received_rport(response,&received,&rport,&transport)==0){ const char *contact=sal_op_get_contact(op); if (!contact){ @@ -1015,7 +1019,7 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){ char *tmp; sal_address_set_domain(addr,received); sal_address_set_port_int(addr,rport); - sal_address_set_transport(addr,transport); + sal_address_set_transport(addr,transport); tmp=sal_address_as_string(addr); ms_message("Contact address updated to %s",tmp); sal_op_set_contact(op,tmp); @@ -1617,19 +1621,17 @@ static void masquerade_via(osip_message_t *msg, const char *ip, const char *port static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer) { osip_contact_t *ctt=NULL; - const char *received; + const char *received; int rport; - SalTransport transport; - char port[20]; - - if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; - eXosip_lock(); - osip_message_get_contact(request,0,&ctt); - if (ctt == NULL) { - /*nothing to update*/ - eXosip_unlock(); - return FALSE; - } + SalTransport transport; + char port[20]; + + if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; + osip_message_get_contact(request,0,&ctt); + if (ctt == NULL) { + /*nothing to update*/ + return FALSE; + } if (ctt->url->host!=NULL){ osip_free(ctt->url->host); } @@ -1640,68 +1642,68 @@ static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_messag snprintf(port,sizeof(port),"%i",rport); ctt->url->port=osip_strdup(port); if (op->masquerade_via) masquerade_via(request,received,port); - - if (transport != SalTransportUDP) { - sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport)); - - } - eXosip_unlock(); - return TRUE; - + + if (transport != SalTransportUDP) { + sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport)); + } + return TRUE; } static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){ - osip_contact_t *ctt=NULL; - SalAddress* ori_contact_address=NULL; - const char *received; + osip_contact_t *ctt=NULL; + SalAddress* ori_contact_address=NULL; + const char *received; int rport; - SalTransport transport; - char* tmp; - osip_message_t *msg=NULL; - Sal* sal=op->base.root; - - if (sal->double_reg==FALSE ) return FALSE; - - if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; - osip_message_get_contact(orig_request,0,&ctt); - osip_contact_to_str(ctt,&tmp); - ori_contact_address = sal_address_new((const char*)tmp); - osip_free(tmp); - /*check if contact is up to date*/ - if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0 - && sal_address_get_port_int(ori_contact_address) == rport - && sal_address_get_transport(ori_contact_address) == transport) { - ms_message("Register has up to date contact, doing nothing."); - return FALSE; - } else ms_message("contact do not match, need to update the register (%s with %s:%i;transport=%s)" - ,tmp - ,received - ,rport - ,sal_transport_to_string(transport)); - - sal_address_destroy(ori_contact_address); - - if (transport == SalTransportUDP) { - eXosip_lock(); - eXosip_register_build_register(op->rid,op->expires,&msg); - if (msg==NULL){ - eXosip_unlock(); - ms_warning("Fail to create a contact updated register."); - return FALSE; - } - if (fix_message_contact(op,msg,last_answer)) { - eXosip_register_send_register(op->rid,msg); - ms_message("Resending new register with updated contact"); - return TRUE; - } else { - ms_warning("Fail to send updated register."); - eXosip_unlock(); - return FALSE; - } - } + SalTransport transport; + char* tmp; + osip_message_t *msg=NULL; + Sal* sal=op->base.root; - update_contact_from_response(op,last_answer); - return FALSE; + if (sal->double_reg==FALSE ) return FALSE; + + if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE; + osip_message_get_contact(orig_request,0,&ctt); + osip_contact_to_str(ctt,&tmp); + ori_contact_address = sal_address_new((const char*)tmp); + + /*check if contact is up to date*/ + if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0 + && sal_address_get_port_int(ori_contact_address) == rport + && sal_address_get_transport(ori_contact_address) == transport) { + ms_message("Register has up to date contact, doing nothing."); + osip_free(tmp); + return FALSE; + } else ms_message("contact do not match, need to update the register (%s with %s:%i;transport=%s)" + ,tmp + ,received + ,rport + ,sal_transport_to_string(transport)); + osip_free(tmp); + sal_address_destroy(ori_contact_address); + + if (transport == SalTransportUDP) { + eXosip_lock(); + eXosip_register_build_register(op->rid,op->expires,&msg); + if (msg==NULL){ + eXosip_unlock(); + ms_warning("Fail to create a contact updated register."); + return FALSE; + } + if (fix_message_contact(op,msg,last_answer)) { + eXosip_register_send_register(op->rid,msg); + eXosip_unlock(); + ms_message("Resending new register with updated contact"); + return TRUE; + } else { + ms_warning("Fail to send updated register."); + eXosip_unlock(); + return FALSE; + } + eXosip_unlock(); + } + + update_contact_from_response(op,last_answer); + return FALSE; } static void registration_success(Sal *sal, eXosip_event_t *ev){ From 8ba552ab693cb648947defac468cd31c311dbad3 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 16 Jun 2011 15:41:36 +0200 Subject: [PATCH 20/51] fix missing declarations --- coreapi/linphonecore.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 8a298332f..12bf72655 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -720,6 +720,10 @@ void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime); */ int linphone_core_get_download_ptime(LinphoneCore *lc); +void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime); + +int linphone_core_get_upload_ptime(LinphoneCore *lc); + /* returns a MSList of PayloadType */ const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc); From 928e9717531c342ec38b00a66dd7fe1f77fd8909 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 20 Jun 2011 11:17:41 +0200 Subject: [PATCH 21/51] update ms2 --- coreapi/lsd.c | 1 - mediastreamer2 | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/coreapi/lsd.c b/coreapi/lsd.c index 1ad7c7db4..f22a5b207 100644 --- a/coreapi/lsd.c +++ b/coreapi/lsd.c @@ -250,7 +250,6 @@ LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, lsd_player_init(&lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd); ms_filter_set_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0]); - ms_filter_enable_synchronous_notifcations (lsd->branches[0].player,TRUE); for(i=1;ibranches[i],mp,MS_FILE_PLAYER_ID,lsd); diff --git a/mediastreamer2 b/mediastreamer2 index 07d1b02eb..1e18ab2f4 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 07d1b02eb57b7fc5cc8e4821c6485df2f138906e +Subproject commit 1e18ab2f4bf3ad6e8cac65b7bc9643ed3b80f455 From 541b186df248fea4b6de5fede96f369ed7c799c7 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 21 Jun 2011 16:18:20 +0200 Subject: [PATCH 22/51] don't add transport=UDP --- coreapi/sal_eXosip2.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 42574dc8f..fd184a40f 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -835,7 +835,7 @@ void sal_op_cancel_authentication(SalOp *h) { static void set_network_origin(SalOp *op, osip_message_t *req){ const char *received=NULL; int rport=5060; - char origin[64]; + char origin[64]={0}; SalTransport transport; if (extract_received_rport(req,&received,&rport,&transport)!=0){ osip_via_t *via=NULL; @@ -1019,7 +1019,8 @@ static void update_contact_from_response(SalOp *op, osip_message_t *response){ char *tmp; sal_address_set_domain(addr,received); sal_address_set_port_int(addr,rport); - sal_address_set_transport(addr,transport); + if (transport!=SalTransportUDP) + sal_address_set_transport(addr,transport); tmp=sal_address_as_string(addr); ms_message("Contact address updated to %s",tmp); sal_op_set_contact(op,tmp); From c971007361d0ae52991e7f2bceead04ac23751b0 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Jun 2011 12:26:41 +0200 Subject: [PATCH 23/51] rename up_ptime into upload_ptime --- coreapi/linphonecore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 651eca134..49a2601da 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -880,7 +880,7 @@ int linphone_core_get_download_ptime(LinphoneCore *lc) { * **/ void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){ - lp_config_set_int(lc->config,"rtp","up_ptime",ptime); + lp_config_set_int(lc->config,"rtp","upload_ptime",ptime); } /** @@ -889,7 +889,7 @@ void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){ * **/ int linphone_core_get_upload_ptime(LinphoneCore *lc){ - return lp_config_get_int(lc->config,"rtp","up_ptime",0); + return lp_config_get_int(lc->config,"rtp","upload_ptime",0); } From c8f4f8f296baa01f5839104327f1707626b7cf63 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Jun 2011 13:06:13 +0200 Subject: [PATCH 24/51] add missing jni --- coreapi/linphonecore_jni.cc | 9 +++++++++ java/common/org/linphone/core/LinphoneCore.java | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 2492e8f61..f858f8d17 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1206,6 +1206,15 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadBandwidth(JNI extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadBandwidth(JNIEnv *env, jobject thiz, jlong lc, jint bw){ linphone_core_set_upload_bandwidth((LinphoneCore *)lc, (int) bw); } + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDownloadPtime(JNIEnv *env, jobject thiz, jlong lc, jint ptime){ + linphone_core_set_download_ptime((LinphoneCore *)lc, (int) ptime); +} + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUploadPtime(JNIEnv *env, jobject thiz, jlong lc, jint ptime){ + linphone_core_set_upload_ptime((LinphoneCore *)lc, (int) ptime); +} + extern "C" int Java_org_linphone_core_LinphoneProxyConfigImpl_getState(JNIEnv* env,jobject thiz,jlong ptr) { return (int) linphone_proxy_config_get_state((const LinphoneProxyConfig *) ptr); } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 1c7dd2ff9..4afe7182f 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -531,6 +531,18 @@ public interface LinphoneCore { void setUploadBandwidth(int bw); void setDownloadBandwidth(int bw); + + /** + * Sets audio packetization interval suggested for remote end. + * @param ptime packetization interval in milliseconds + */ + void setDownloadPtime(int ptime); + + /** + * Sets audio packetization interval sent to remote end. + * @param ptime packetization interval in milliseconds + */ + void setUploadPtime(int ptime); void setPreferredVideoSize(VideoSize vSize); From 044ddc63edfa92cfd4de8f91f344ec4d2bcbb2a6 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 22 Jun 2011 20:28:40 +0200 Subject: [PATCH 25/51] add sip option reuse_authorization to reuse authorization header for subsequente register --- coreapi/linphonecore.c | 1 + coreapi/sal.c | 1 + coreapi/sal.h | 1 + coreapi/sal_eXosip2.c | 8 ++++++-- coreapi/sal_eXosip2.h | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 651eca134..ee7c7b90c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -466,6 +466,7 @@ static void sip_config_read(LinphoneCore *lc) sal_use_rport(lc->sal,lp_config_get_int(lc->config,"sip","use_rport",1)); sal_use_101(lc->sal,lp_config_get_int(lc->config,"sip","use_101",1)); + sal_reuse_authorization(lc->sal, lp_config_get_int(lc->config,"sip","reuse_authorization",0)); tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0); linphone_core_set_use_rfc2833_for_dtmf(lc,tmp); diff --git a/coreapi/sal.c b/coreapi/sal.c index 92b82d52c..b237e9ad9 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -329,3 +329,4 @@ void sal_auth_info_delete(const SalAuthInfo* auth_info) { if (auth_info->password) ms_free(auth_info->password); ms_free((void*)auth_info); } + diff --git a/coreapi/sal.h b/coreapi/sal.h index af1ddc367..647353214 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -267,6 +267,7 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value); unsigned int sal_get_keepalive_period(Sal *ctx); void sal_use_session_timers(Sal *ctx, int expires); void sal_use_double_registrations(Sal *ctx, bool_t enabled); +void sal_reuse_authorization(Sal *ctx, bool_t enabled); void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec); void sal_use_rport(Sal *ctx, bool_t use_rports); void sal_use_101(Sal *ctx, bool_t use_101); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 42574dc8f..9836c7dfe 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -279,6 +279,7 @@ Sal * sal_init(){ sal->double_reg=TRUE; sal->use_rports=TRUE; sal->use_101=TRUE; + sal->reuse_authorization=FALSE; return sal; } @@ -793,7 +794,7 @@ int sal_call_terminate(SalOp *h){ eXosip_lock(); err=eXosip_call_terminate(h->cid,h->did); eXosip_unlock(); - pop_auth_from_exosip(); + if (!h->base.root->reuse_authorization) pop_auth_from_exosip(); if (err!=0){ ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did); } @@ -816,7 +817,7 @@ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ eXosip_default_action(h->pending_auth); eXosip_unlock(); ms_message("eXosip_default_action() done"); - pop_auth_from_exosip(); + if (!h->base.root->reuse_authorization) pop_auth_from_exosip(); if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/ h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/ @@ -2206,3 +2207,6 @@ int sal_call_update(SalOp *h, const char *subject){ eXosip_unlock(); return err; } +void sal_reuse_authorization(Sal *ctx, bool_t value) { + ctx->reuse_authorization=value; +} diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index a050f5133..201cb65a9 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -44,6 +44,7 @@ struct Sal{ bool_t double_reg; bool_t use_rports; bool_t use_101; + bool_t reuse_authorization; }; struct SalOp{ From 818c21196d1abaecb2fffd7726038060f818fe79 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 24 Jun 2011 11:55:06 +0200 Subject: [PATCH 26/51] remove register transaction in sal_op_release --- coreapi/sal_eXosip2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 88a378da0..2bdb5ec29 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -193,6 +193,7 @@ void sal_op_release(SalOp *op){ eXosip_event_free(op->pending_auth); if (op->rid!=-1){ sal_remove_register(op->base.root,op->rid); + eXosip_register_remove(op->rid); } if (op->cid!=-1){ ms_message("Cleaning cid %i",op->cid); From d06faa9190f3936793d07589de2a08340881ff67 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 24 Jun 2011 14:11:47 +0200 Subject: [PATCH 27/51] keep local payload types offered in call profile in case the remote end wants to use them despite it didn't accepted them. --- coreapi/linphonecall.c | 5 +---- coreapi/offeranswer.c | 23 ++++++++++++++++++++++- coreapi/sal.h | 4 ++++ coreapi/sal_eXosip2.c | 4 ++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 36a41186e..7e6e0380a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -783,9 +783,6 @@ static void post_configure_audio_streams(LinphoneCall*call){ } } - - - static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *md, const SalStreamDescription *desc, int *used_pt){ int bw; const MSList *elem; @@ -800,7 +797,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m PayloadType *pt=(PayloadType*)elem->data; int number; - if (first) { + if ((pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND) && first) { if (desc->type==SalAudio){ linphone_core_update_allocated_audio_bandwidth_in_call(call,pt); up_ptime=linphone_core_get_upload_ptime(lc); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 34d21fc0f..3e054508b 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -61,7 +61,7 @@ static PayloadType * find_payload_type_best_match(const MSList *l, const Payload } static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){ - const MSList *e2; + const MSList *e2,*e1; MSList *res=NULL; PayloadType *matched; bool_t found_codec=FALSE; @@ -85,6 +85,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t newp=payload_type_clone(matched); if (p2->send_fmtp) payload_type_set_send_fmtp(newp,p2->send_fmtp); + newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; res=ms_list_append(res,newp); /* we should use the remote numbering even when parsing a response */ payload_type_set_number(newp,remote_number); @@ -104,6 +105,26 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t ms_message("No match for %s/%i",p2->mime_type,p2->clock_rate); } } + if (reading_response){ + /* add remaning local payload as CAN_RECV only so that if we are in front of a non-compliant equipment we are still able to decode the RTP stream*/ + for(e1=local;e1!=NULL;e1=e1->next){ + PayloadType *p1=(PayloadType*)e1->data; + bool_t found=FALSE; + for(e2=res;e2!=NULL;e2=e2->next){ + PayloadType *p2=(PayloadType*)e2->data; + if (payload_type_get_number(p2)==payload_type_get_number(p1)){ + found=TRUE; + break; + } + } + if (!found){ + ms_message("Adding %s/%i for compatibility, just in case.",p1->mime_type,p1->clock_rate); + p1=payload_type_clone(p1); + p1->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV; + res=ms_list_append(res,p1); + } + } + } return res; } diff --git a/coreapi/sal.h b/coreapi/sal.h index af1ddc367..8ab339a6e 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -319,6 +319,7 @@ int sal_call_send_dtmf(SalOp *h, char dtmf); int sal_call_terminate(SalOp *h); bool_t sal_call_autoanswer_asked(SalOp *op); void sal_call_send_vfu_request(SalOp *h); +int sal_call_is_offerer(const SalOp *h); /*Registration*/ int sal_register(SalOp *op, const char *proxy, const char *from, int expires); @@ -343,6 +344,9 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus s /*ping: main purpose is to obtain its own contact address behind firewalls*/ int sal_ping(SalOp *op, const char *from, const char *to); +#define PAYLOAD_TYPE_FLAG_CAN_RECV PAYLOAD_TYPE_USER_FLAG_1 +#define PAYLOAD_TYPE_FLAG_CAN_SEND PAYLOAD_TYPE_USER_FLAG_2 + #define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n); #define payload_type_get_number(pt) ((int)(long)(pt)->user_data) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index fd184a40f..363adfdeb 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -509,6 +509,10 @@ static void sdp_process(SalOp *h){ } +int sal_call_is_offerer(const SalOp *h){ + return h->sdp_offering; +} + int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){ if (desc) sal_media_description_ref(desc); From 47a922928ea510612fd5c100d01dbb51d3e3b84c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 27 Jun 2011 15:02:53 +0200 Subject: [PATCH 28/51] windows build updated --- linphone-deps.filelist | 6 +++--- mediastreamer2 | 2 +- oRTP | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/linphone-deps.filelist b/linphone-deps.filelist index 22e069ed8..c15e85ed6 100755 --- a/linphone-deps.filelist +++ b/linphone-deps.filelist @@ -1,10 +1,10 @@ -./bin/avcodec-52.dll -./bin/avutil-50.dll +./bin/avcodec-53.dll +./bin/avutil-51.dll ./bin/libeXosip2-6.dll ./bin/libogg-0.dll ./bin/libtheora-0.dll ./bin/libxml2-2.dll ./bin/libosip2-6.dll ./bin/libosipparser2-6.dll -./bin/swscale-0.dll +./bin/swscale-2.dll diff --git a/mediastreamer2 b/mediastreamer2 index 1e18ab2f4..4e1f80ed1 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1e18ab2f4bf3ad6e8cac65b7bc9643ed3b80f455 +Subproject commit 4e1f80ed17226db3afaae21bbb7295f2a20eb55b diff --git a/oRTP b/oRTP index 3af8aa68f..939fc5cb4 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 3af8aa68f253d802b674cc1807115e4556c0fafa +Subproject commit 939fc5cb4735de8c43619a1c1096855078e5207e From 999e7c141076fea1ed2ddc2444273ef37c426096 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 1 Jul 2011 15:46:44 +0200 Subject: [PATCH 29/51] update mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 1e18ab2f4..4e1f80ed1 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1e18ab2f4bf3ad6e8cac65b7bc9643ed3b80f455 +Subproject commit 4e1f80ed17226db3afaae21bbb7295f2a20eb55b From 09c1d5124524e00d425a2d96c372691a912b3b4a Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 1 Jul 2011 16:20:55 +0200 Subject: [PATCH 30/51] add mingw libpthread into setup.exe --- Makefile.am | 1 + linphone-deps.filelist | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index d07aad6c6..b972eba81 100644 --- a/Makefile.am +++ b/Makefile.am @@ -98,6 +98,7 @@ other-cherrypick: /mingw/bin/libstdc++-6.dll \ /mingw/bin/libintl-8.dll \ /mingw/bin/libiconv-2.dll \ + /mingw/bin/libpthread-2.dll \ $(INSTALLDIR_WITH_PREFIX)/bin/. diff --git a/linphone-deps.filelist b/linphone-deps.filelist index c15e85ed6..de01182ca 100755 --- a/linphone-deps.filelist +++ b/linphone-deps.filelist @@ -7,4 +7,3 @@ ./bin/libosip2-6.dll ./bin/libosipparser2-6.dll ./bin/swscale-2.dll - From 659ea31d87f02c4f563c707c366105f87b5b750c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 1 Jul 2011 20:26:04 +0200 Subject: [PATCH 31/51] update ortp --- oRTP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oRTP b/oRTP index 939fc5cb4..a94f569ca 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 939fc5cb4735de8c43619a1c1096855078e5207e +Subproject commit a94f569ca7257c11b0aa09dae10c7f77d0b46e9f From b2e014dd9403144c085e21284aff2462b4c305a6 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 6 Jul 2011 18:21:41 +0200 Subject: [PATCH 32/51] fix for inband dtmf not sent --- coreapi/sal.h | 8 ++++++-- mediastreamer2 | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/coreapi/sal.h b/coreapi/sal.h index 6a27f1331..47286b09c 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -28,6 +28,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mscommon.h" +/*Dirty hack, keep in sync with mediastreamer2/include/mediastream.h */ +#ifndef PAYLOAD_TYPE_FLAG_CAN_RECV +#define PAYLOAD_TYPE_FLAG_CAN_RECV PAYLOAD_TYPE_USER_FLAG_1 +#define PAYLOAD_TYPE_FLAG_CAN_SEND PAYLOAD_TYPE_USER_FLAG_2 +#endif struct Sal; typedef struct Sal Sal; @@ -345,8 +350,7 @@ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus s /*ping: main purpose is to obtain its own contact address behind firewalls*/ int sal_ping(SalOp *op, const char *from, const char *to); -#define PAYLOAD_TYPE_FLAG_CAN_RECV PAYLOAD_TYPE_USER_FLAG_1 -#define PAYLOAD_TYPE_FLAG_CAN_SEND PAYLOAD_TYPE_USER_FLAG_2 + #define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n); #define payload_type_get_number(pt) ((int)(long)(pt)->user_data) diff --git a/mediastreamer2 b/mediastreamer2 index 4e1f80ed1..0cd097126 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 4e1f80ed17226db3afaae21bbb7295f2a20eb55b +Subproject commit 0cd097126ba076cdd1d4fff0b5c33549b75bb28a From c94544d578087478e1cb16adb3a45816f866281c Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Sun, 10 Jul 2011 23:39:39 +0200 Subject: [PATCH 33/51] fix vp8 compilation issue --- configure.ac | 6 +++++- mediastreamer2 | 2 +- oRTP | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 556941c0e..08bcd8bf9 100644 --- a/configure.ac +++ b/configure.ac @@ -320,7 +320,11 @@ if test "$video" = "true"; then if test "$enable_x11" = "true"; then AC_CHECK_HEADERS(X11/Xlib.h) - AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11") + if test "$build_macos" = "yes"; then + X11_LIBS="-L/usr/X11/lib -lX11" + else + AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11") + fi AC_SUBST(X11_LIBS) fi AC_DEFINE(VIDEO_ENABLED,1,[defined if video support is available]) diff --git a/mediastreamer2 b/mediastreamer2 index 0cd097126..d1ea30fb5 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0cd097126ba076cdd1d4fff0b5c33549b75bb28a +Subproject commit d1ea30fb58954005d1ac3c2a71fbcfcb85d3bf40 diff --git a/oRTP b/oRTP index a94f569ca..662a65869 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit a94f569ca7257c11b0aa09dae10c7f77d0b46e9f +Subproject commit 662a65869902a927673d9ceff10781e217ca8e9d From ce1326043817b304724337005a34faed7d26c27e Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 15 Jul 2011 22:03:24 +0200 Subject: [PATCH 34/51] API and makefiles for ZRTP support. --- README.zrtp | 94 ++++++++++++ build/android/Android.mk | 15 +- console/linphonec.c | 11 ++ .../core/tutorials/TutorialBuddyStatus.java | 3 +- .../core/tutorials/TutorialChatRoom.java | 2 +- .../core/tutorials/TutorialHelloWorld.java | 2 + .../core/tutorials/TutorialRegistration.java | 1 + coreapi/linphonecall.c | 109 ++++++++++++++ coreapi/linphonecore.c | 7 +- coreapi/linphonecore.h | 18 ++- coreapi/linphonecore_jni.cc | 55 +++++++ coreapi/private.h | 1 + .../org/linphone/core/LinphoneCall.java | 5 + .../org/linphone/core/LinphoneCore.java | 3 + .../linphone/core/LinphoneCoreListener.java | 138 ++++++++++-------- mediastreamer2 | 2 +- oRTP | 2 +- 17 files changed, 398 insertions(+), 70 deletions(-) create mode 100644 README.zrtp diff --git a/README.zrtp b/README.zrtp new file mode 100644 index 000000000..c71c8d2d7 --- /dev/null +++ b/README.zrtp @@ -0,0 +1,94 @@ +ZRTP guide + +== Downloads == +- SRTP +http://sourceforge.net/projects/srtp/ +or "apt-get source libsrtp0" on Debian + +- ZRTP (libzrtpcpp-2.0) +http://www.gnutelephony.org/index.php/GNU_ZRTP + + +== Patch libzrtpcpp == +Index: src/ZIDFile.cpp +=================================================================== +--- src/ZIDFile.cpp (révision 754) ++++ src/ZIDFile.cpp (copie de travail) +@@ -78,10 +78,11 @@ + + // create save file name, rename and re-open + // if rename fails, just unlink old ZID file and create a brand new file +- // just a little inconnvenience for the user, need to verify new SAS ++ // just a little inconvenience for the user, need to verify new SAS + std::string fn = std::string(name) + std::string(".save"); + if (rename(name, fn.c_str()) < 0) { +- unlink(name); ++ // unlink(name); + createZIDFile(name); + return; + } +Index: src/libzrtpcpp/ZrtpCallback.h +=================================================================== +--- src/libzrtpcpp/ZrtpCallback.h (révision 754) ++++ src/libzrtpcpp/ZrtpCallback.h (copie de travail) +@@ -27,7 +27,7 @@ + + #include + #include +-#include ++//#include + #include + + /** +Index: src/libzrtpcpp/ZIDRecord.h +=================================================================== +--- src/libzrtpcpp/ZIDRecord.h (révision 754) ++++ src/libzrtpcpp/ZIDRecord.h (copie de travail) +@@ -33,7 +33,7 @@ + + #include + #include +-#include ++//#include + + #define IDENTIFIER_LEN 12 + #define RS_LENGTH 32 +Index: CMakeLists.txt +=================================================================== +--- CMakeLists.txt (révision 754) ++++ CMakeLists.txt (copie de travail) +@@ -124,11 +124,15 @@ + if(CMAKE_COMPILER_IS_GNUCXX) + add_definitions(-Wno-long-long -Wno-char-subscripts) + add_definitions(-Wall -ansi -pedantic) ++ add_definitions(-DNEW_STDCPP) + endif() + + add_subdirectory(src) +-add_subdirectory(demo) + ++if (enable_ccrtp) ++ add_subdirectory(demo) ++endif() ++ + if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package/) + MESSAGE(STATUS "package dir not found") + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/) + + + +== Create simlinks or move folders == +submodules/external/srtp -> path_to_your_srtp_source +submodules/external/libzrtpcpp -> path_to_your_patched_zrtpcpp_source + + + +== Compilation for Android == +ndk-build BUILD_GPLV3_ZRTP=1 -j5 + + +== Compilation for Desktop version == +First ortp: ./autogen.sh && ./configure --enable-zrtp && make -j5 && sudo make install +Then mediastreamer2: ./autogen.sh && ./configure && make -j5 && sudo make install +Finally linphone: ./autogen.sh && ./configure --enable-external-ortp && make -j5 && sudo make install + diff --git a/build/android/Android.mk b/build/android/Android.mk index 468afbfa3..7c9d13491 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -61,8 +61,7 @@ LOCAL_CFLAGS += \ -DENABLE_TRACE \ -DLINPHONE_VERSION=\"3.4.0\" \ -DLINPHONE_PLUGINS_DIR=\"\\tmp\" \ - -DLOG_DOMAIN=$(MY_LOG_DOMAIN) \ - -UNE_BONNE_PIPE_CA_FAIT_DU_BIEN + -DLOG_DOMAIN=$(MY_LOG_DOMAIN) LOCAL_CFLAGS += -DIN_LINPHONE @@ -115,6 +114,7 @@ LOCAL_SHARED_LIBRARIES += \ libavutil endif + LOCAL_STATIC_LIBRARIES += libspeex @@ -127,6 +127,17 @@ LOCAL_SRC_FILES += $(LIBLINPHONE_EXTENDED_SRC_FILES) LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +ifeq ($(BUILD_GPLV3_ZRTP),1) +LOCAL_SHARED_LIBRARIES += \ + libzrtpcpp +endif + +ifeq ($(BUILD_SRTP),1) +LOCAL_SHARED_LIBRARIES += \ + libsrtp +endif +endif LOCAL_MODULE := liblinphone include $(BUILD_SHARED_LIBRARY) diff --git a/console/linphonec.c b/console/linphonec.c index 40a243607..fef795d86 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -323,6 +323,16 @@ static void linphonec_call_updated(LinphoneCall *call){ } } +static void linphonec_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t encrypted, const char *auth_token) { + long id=(long)linphone_call_get_user_pointer (call); + if (!encrypted) { + linphonec_out("Call %i is not encrypted.\n", id); + } else { + linphonec_out("Call %i is encrypted and auth token is %s.\n", id, + (auth_token != NULL) ? auth_token : "absent"); + } +} + static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState st, const char *msg){ char *from=linphone_call_get_remote_address_as_string(call); long id=(long)linphone_call_get_user_pointer (call); @@ -626,6 +636,7 @@ main (int argc, char *argv[]) { linphonec_vtable.dtmf_received=linphonec_dtmf_received; linphonec_vtable.refer_received=linphonec_display_refer; linphonec_vtable.notify_recv=linphonec_notify_received; + linphonec_vtable.call_encryption_changed=linphonec_call_encryption_changed; if (! linphonec_init(argc, argv) ) exit(EXIT_FAILURE); diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index d5351d99c..e7db170b8 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -97,7 +97,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} - + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public static void main(String[] args) { @@ -231,5 +231,4 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { } - } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index 9309779bf..5837876cb 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -75,7 +75,7 @@ public class TutorialChatRoom implements LinphoneCoreListener { public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} - + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) { write("Message ["+message+"] received from ["+from.asString()+"]"); diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java index d9fdd4f41..30510fd84 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java @@ -69,6 +69,8 @@ public class TutorialHelloWorld implements LinphoneCoreListener { public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} + /* * Call state notification listener */ diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index c00ff9b73..8af45162c 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -80,6 +80,7 @@ public class TutorialRegistration implements LinphoneCoreListener { public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public static void main(String[] args) { // Check tutorial was called with the right number of arguments diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7e6e0380a..7f9c12c20 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -40,6 +40,102 @@ static MSWebCam *get_nowebcam_device(){ } #endif +static const char* get_zrtp_identifier(LinphoneCore *lc){ + const char *confZid=lp_config_get_string(lc->config,"rtp","zid",NULL); + if (confZid != NULL) { + return confZid; + } else { + int32_t *zid=calloc(3,32); + int i=0; + for(;i<3;i++) { + zid[i]=rand(); + } + lp_config_set_string(lc->config,"rtp","zid",(char*)zid); + return lp_config_get_string(lc->config,"rtp","zid",NULL); + } +} + +const char* linphone_call_get_authentication_token(LinphoneCall *call){ + return call->audiostream->auth_token; +} + +bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){ + return call->audiostream->auth_token_verified; +} +bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) { + // Check ZRTP encryption in audiostream + if (!call->audiostream->encrypted) { + return FALSE; + } + +#ifdef VIDEO_ENABLED + // If video enabled, check ZRTP encryption in videostream + const LinphoneCallParams *params=linphone_call_get_current_params(call); + if (params->has_video && !call->videostream->encrypted) { + return FALSE; + } +#endif + + return TRUE; +} + +static void propagate_encryption_changed(LinphoneCall *call){ + if (call->core->vtable.call_encryption_changed == NULL) return; + + if (!linphone_call_are_all_streams_encrypted(call)) { + call->core->vtable.call_encryption_changed(call->core, call, FALSE, NULL); + } else { + call->core->vtable.call_encryption_changed(call->core, call, TRUE, call->audiostream->auth_token); + } +} + +#ifdef VIDEO_ENABLED +static void linphone_call_videostream_encryption_changed(void *data, bool_t encrypted){ + ms_message("Video stream is %s", encrypted ? "encrypted" : "not encrypted"); + + LinphoneCall *call = (LinphoneCall *)data; + call->videostream->encrypted=encrypted; + propagate_encryption_changed(call); +} +#endif + +static void linphone_call_audiostream_encryption_changed(void *data, bool_t encrypted) { + ms_message("Audio stream is %s ", encrypted ? "encrypted" : "not encrypted"); + + LinphoneCall *call = (LinphoneCall *)data; + call->audiostream->encrypted=encrypted; + propagate_encryption_changed(call); + + +#ifdef VIDEO_ENABLED + // Enable video encryption + const LinphoneCallParams *params=linphone_call_get_current_params(call); + if (params->has_video) { + ms_message("Trying to enable encryption on video stream"); + OrtpZrtpParams params; + params.zid=get_zrtp_identifier(call->core); + params.zid_file=NULL; //unused + OrtpZrtpUiCb cbs={0}; + cbs.data=call; + cbs.encryption_changed=linphone_call_videostream_encryption_changed; + params.ui_cbs=&cbs; + video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms); + } +#endif +} + + +static void linphone_call_audiostream_auth_token_ready(void *data, const char* auth_token, bool_t verified) { + LinphoneCall *call=(LinphoneCall *)data; + if (call->audiostream->auth_token != NULL) + ms_free(call->audiostream->auth_token); + + call->audiostream->auth_token=ms_strdup(auth_token); + call->audiostream->auth_token_verified=verified; + + ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified"); +} + static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){ MSList *l=NULL; @@ -1017,6 +1113,18 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut call->playing_ringbacktone=send_ringbacktone; call->up_bw=linphone_core_get_upload_bandwidth(lc); + if (ortp_zrtp_available()) { + OrtpZrtpParams params; + params.zid=get_zrtp_identifier(lc); + params.zid_file=lc->zrtp_secrets_cache; + OrtpZrtpUiCb cbs={0}; + cbs.data=call; + cbs.encryption_changed=linphone_call_audiostream_encryption_changed; + cbs.sas_ready=linphone_call_audiostream_auth_token_ready; + params.ui_cbs=&cbs; + audio_stream_enable_zrtp(call->audiostream,¶ms); + } + goto end; end: ms_free(cname); @@ -1268,3 +1376,4 @@ void linphone_call_log_completed(LinphoneCall *call){ call_logs_write_to_config_file(lc); } + diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 934ebefa6..02647bfa4 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4210,4 +4210,9 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook ms_error("linphone_core_remove_iterate_hook(): No such hook found."); } - +void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ + if (lc->zrtp_secrets_cache != NULL) { + ms_free(lc->zrtp_secrets_cache); + } + lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 12bf72655..3d263082d 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -527,6 +527,9 @@ const char *linphone_global_state_to_string(LinphoneGlobalState gs); typedef void (*LinphoneGlobalStateCb)(struct _LinphoneCore *lc, LinphoneGlobalState gstate, const char *message); /**Call state notification callback prototype*/ typedef void (*LinphoneCallStateCb)(struct _LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message); +/**Call encryption changed callback prototype*/ +typedef void (*CallEncryptionChangedCb)(struct _LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token); + /** @ingroup Proxies * Registration state notification callback prototype * */ @@ -600,6 +603,7 @@ typedef struct _LinphoneVTable{ DisplayMessageCb display_warning;/** Callback to display a warning to the user */ DisplayUrlCb display_url; ShowInterfaceCb show; /**< Notifies the application that it should show up*/ + CallEncryptionChangedCb call_encryption_changed; /** #include "linphonecore_utils.h" +#include #include "mediastreamer2/msjava.h" @@ -89,29 +90,39 @@ public: vTable.global_state_changed = globalStateChange; vTable.registration_state_changed = registrationStateChange; vTable.call_state_changed = callStateChange; + //vTable.call_encryption_changed = callEncryptionChange; vTable.text_received = text_received; vTable.new_subscription_request = new_subscription_request; vTable.notify_presence_recv = notify_presence_recv; listernerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); + /*displayStatus(LinphoneCore lc,String message);*/ displayStatusId = env->GetMethodID(listernerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); + /*void generalState(LinphoneCore lc,int state); */ globalStateId = env->GetMethodID(listernerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState")); globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;"); + /*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/ registrationStateId = env->GetMethodID(listernerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState")); registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;"); + /*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/ callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State")); callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); + + /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ + callEncryptionChangedId=env->GetMethodID(listernerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); + /*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/ ecCalibrationStatusId = env->GetMethodID(listernerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V"); ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus")); ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;"); + /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); @@ -176,6 +187,8 @@ public: jmethodID callStateId; jmethodID callStateFromIntId; + jmethodID callEncryptionChangedId; + jclass ecCalibratorStatusClass; jmethodID ecCalibrationStatusId; jmethodID ecCalibratorStatusFromIntId; @@ -263,6 +276,21 @@ public: ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)state), message ? env->NewStringUTF(message) : NULL); } + static void callEncryptionChange(LinphoneCore *lc, LinphoneCall* call, bool_t encrypted,const char* authentication_token) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); + env->CallVoidMethod(lcData->listener + ,lcData->callEncryptionChangedId + ,lcData->core + ,env->NewObject(lcData->callClass,lcData->callCtrId,(jlong)call) + ,encrypted + ,authentication_token ? env->NewStringUTF(authentication_token) : NULL); + } static void notify_presence_recv (LinphoneCore *lc, LinphoneFriend *my_friend) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -1268,6 +1296,9 @@ extern "C" jboolean Java_org_linphone_core_Version_nativeHasNeon(JNIEnv *env){ } return 0; } +extern "C" jboolean Java_org_linphone_core_Version_nativeHasZrtp(JNIEnv *env){ + return ortp_zrtp_available(); +} extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_pauseCall(JNIEnv *env,jobject thiz,jlong pCore, jlong pCall) { return linphone_core_pause_call((LinphoneCore *) pCore, (LinphoneCall *) pCall); @@ -1278,3 +1309,27 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_pauseAllCalls(JNIEnv *en extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_resumeCall(JNIEnv *env,jobject thiz,jlong pCore, jlong pCall) { return linphone_core_resume_call((LinphoneCore *) pCore, (LinphoneCall *) pCall); } + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setZrtpSecretsCache(JNIEnv *env,jobject thiz,jlong pCore, jstring jFile) { + if (jFile) { + const char* cFile=env->GetStringUTFChars(jFile, NULL); + linphone_core_set_zrtp_secrets_file((LinphoneCore *) pCore,cFile); + env->ReleaseStringUTFChars(jFile, cFile); + } else { + linphone_core_set_zrtp_secrets_file((LinphoneCore *) pCore,NULL); + } +} + +extern "C" jstring Java_org_linphone_core_LinphoneCallImpl_getAuthenticationToken(JNIEnv* env,jobject thiz,jlong ptr) { + LinphoneCall *call = (LinphoneCall *) ptr; + const char* token = linphone_call_get_authentication_token(call); + if (token == NULL) return NULL; + return env->NewStringUTF(token); +} +extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isAuthenticationTokenVerified(JNIEnv* env,jobject thiz,jlong ptr) { + LinphoneCall *call = (LinphoneCall *) ptr; + return linphone_call_get_authentication_token_verified(call); +} +extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_areStreamsEncrypted(JNIEnv* env,jobject thiz,jlong ptr) { + return linphone_call_are_all_streams_encrypted((LinphoneCall *) ptr); +} diff --git a/coreapi/private.h b/coreapi/private.h index 4739c0c70..7fd8f1934 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -440,6 +440,7 @@ struct _LinphoneCore bool_t network_reachable; bool_t use_preview_window; bool_t ringstream_autorelease; + char* zrtp_secrets_cache; }; bool_t linphone_core_can_we_add_call(LinphoneCore *lc); diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index e0f7cde34..a6edf1b7e 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -214,4 +214,9 @@ public interface LinphoneCall { * See getCurrentQuality() for more details about quality measurement. */ float getAverageQuality(); + + + String getAuthenticationToken(); + boolean isAuthenticationTokenVerified(); + boolean areStreamsEncrypted(); } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 4afe7182f..bb52cc874 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -581,4 +581,7 @@ public interface LinphoneCore { boolean pauseCall(LinphoneCall call); boolean resumeCall(LinphoneCall call); boolean pauseAllCalls(); + + void setZrtpSecretsCache(String file); + } diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index ddd58a3ac..cfe43895e 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ + */ package org.linphone.core; @@ -27,65 +27,81 @@ public interface LinphoneCoreListener { /**< Notifies the application that it should show up * @return */ - public void show(LinphoneCore lc); - /**< Ask the application some authentication information - * @return */ - public void authInfoRequested(LinphoneCore lc,String realm,String username); - /**< Callback that notifies various events with human readable text. - * @return */ - public void displayStatus(LinphoneCore lc,String message); - /**< Callback to display a message to the user - * @return */ - public void displayMessage(LinphoneCore lc,String message); - /** Callback to display a warning to the user - * @return */ - public void displayWarning(LinphoneCore lc,String message); - /** General State notification - * @param state LinphoneCore.State - * @return - * */ - public void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message); - /** Call State notification - * @param state LinphoneCall.State - * @return - * */ - - public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message); - /** - * Registration state notification - * */ - public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage); - /** - * Reports that a new subscription request has been received and wait for a decision. - *Status on this subscription request is notified by changing policy for this friend - *@param lc LinphoneCore - *@param lf LinphoneFriend corresponding to the subscriber - *@param url of the subscriber - * - */ - public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url); - /** - * Report status change for a friend previously added to LinphoneCore. - * @param lc LinphoneCore - * @param lf updated LinphoneFriend - */ - public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf); - /** - * invoked when a new text message is received - * @param lc LinphoneCore - * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. - * @param from LinphoneAddress from - * @param message incoming message - */ - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message); - /** - * Invoked when echo cancalation calibration is completed - * @param lc LinphoneCore - * @param status - * @param delay_ms echo delay - * @param data - */ - void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data); - + void show(LinphoneCore lc); + + /**< Ask the application some authentication information + * @return */ + void authInfoRequested(LinphoneCore lc,String realm,String username); + + /**< Callback that notifies various events with human readable text. + * @return */ + void displayStatus(LinphoneCore lc,String message); + + /**< Callback to display a message to the user + * @return */ + void displayMessage(LinphoneCore lc,String message); + + /** Callback to display a warning to the user + * @return */ + void displayWarning(LinphoneCore lc,String message); + + /** General State notification + * @param state LinphoneCore.State + * @return + * */ + void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message); + + /** Call State notification + * @param state LinphoneCall.State + * @return + * */ + void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message); + + /** + * Callback to display change in encryption state. + * @param encrypted true if all streams of the call are encrypted + * @param authenticationToken token like ZRTP SAS that may be displayed to user + */ + void callEncryptionChanged(LinphoneCore lc, LinphoneCall call, boolean encrypted, String authenticationToken); + + /** + * Registration state notification + * */ + void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage); + + /** + * Reports that a new subscription request has been received and wait for a decision. + *Status on this subscription request is notified by changing policy for this friend + *@param lc LinphoneCore + *@param lf LinphoneFriend corresponding to the subscriber + *@param url of the subscriber + * + */ + void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url); + + /** + * Report status change for a friend previously added to LinphoneCore. + * @param lc LinphoneCore + * @param lf updated LinphoneFriend + */ + void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf); + + /** + * invoked when a new text message is received + * @param lc LinphoneCore + * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. + * @param from LinphoneAddress from + * @param message incoming message + */ + void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message); + + /** + * Invoked when echo cancalation calibration is completed + * @param lc LinphoneCore + * @param status + * @param delay_ms echo delay + * @param data + */ + void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data); } diff --git a/mediastreamer2 b/mediastreamer2 index d1ea30fb5..909125059 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d1ea30fb58954005d1ac3c2a71fbcfcb85d3bf40 +Subproject commit 9091250591e54e6533cea8ba8c203f6f4f47550d diff --git a/oRTP b/oRTP index 662a65869..9cdfa6c82 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 662a65869902a927673d9ceff10781e217ca8e9d +Subproject commit 9cdfa6c826b2a2701122a50ed3c78afa8ef17ec6 From ff7f866dd9e4bf9c8c239d8fce2d34dd14b3ffe5 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Date: Tue, 19 Jul 2011 14:18:13 +0200 Subject: [PATCH 35/51] Add TLS support to Linphone --- coreapi/linphonecore.c | 17 ++++++++++++++--- coreapi/proxy.c | 8 ++++++-- coreapi/sal.c | 16 ++++++++-------- coreapi/sal_eXosip2.c | 7 ++++--- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 02647bfa4..847316d07 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -487,6 +487,11 @@ static void sip_config_read(LinphoneCore *lc) } else { tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",0); } + if (lp_config_get_int(lc->config,"sip","sip_tls_random_port",0)) { + tr.tls_port=(0xDFF&+random())+1024; + } else { + tr.tls_port=lp_config_get_int(lc->config,"sip","sip_tls_port",0); + } /*start listening on ports*/ linphone_core_set_sip_transports(lc,&tr); @@ -1358,7 +1363,7 @@ void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,bool_t use_rfc2833) int linphone_core_get_sip_port(LinphoneCore *lc) { LCSipTransports *tr=&lc->sip_conf.transports; - return tr->udp_port>0 ? tr->udp_port : tr->tcp_port; + return tr->udp_port>0 ? tr->udp_port : (tr->tcp_port > 0 ? tr->tcp_port : tr->tls_port); } static char _ua_name[64]="Linphone"; @@ -1419,13 +1424,18 @@ static int apply_transports(LinphoneCore *lc){ sal_unlisten_ports (sal); if (tr->udp_port>0){ if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){ - transport_error(lc,"UDP",tr->udp_port); + transport_error(lc,"udp",tr->udp_port); return -1; } } if (tr->tcp_port>0){ if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){ - transport_error(lc,"TCP",tr->tcp_port); + transport_error(lc,"tcp",tr->tcp_port); + } + } + if (tr->tls_port>0){ + if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,TRUE)!=0){ + transport_error(lc,"tls",tr->tls_port); } } apply_user_agent(lc); @@ -3746,6 +3756,7 @@ void sip_config_uninit(LinphoneCore *lc) sip_config_t *config=&lc->sip_conf; lp_config_set_int(lc->config,"sip","sip_port",config->transports.udp_port); lp_config_set_int(lc->config,"sip","sip_tcp_port",config->transports.tcp_port); + lp_config_set_int(lc->config,"sip","sip_tls_port",config->transports.tls_port); lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname); lp_config_set_string(lc->config,"sip","contact",config->contact); lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index ff13f839e..dda1bc789 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -258,8 +258,12 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){ linphone_address_set_display_name(contact,NULL); linphone_core_get_sip_transports(obj->lc,&tr); - if (tr.udp_port <= 0 && tr.tcp_port>0) { - sal_address_set_param(contact,"transport","TCP"); + if (tr.udp_port <= 0) { + if (tr.tcp_port>0) { + sal_address_set_param(contact,"transport","tcp"); + } else if (tr.tls_port>0) { + sal_address_set_param(contact,"transport","tls"); + } } ret=linphone_address_as_string(contact); linphone_address_destroy(contact); diff --git a/coreapi/sal.c b/coreapi/sal.c index b237e9ad9..e30e86be4 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -26,10 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sal.h" const char* sal_transport_to_string(SalTransport transport) { switch (transport) { - case SalTransportUDP:return "UDP"; - case SalTransportTCP: return "TCP"; - case SalTransportTLS:return "TLS"; - case SalTransportDTLS:return "DTLS"; + case SalTransportUDP:return "udp"; + case SalTransportTCP: return "tcp"; + case SalTransportTLS:return "tls"; + case SalTransportDTLS:return "dtls"; default: { ms_fatal("Unexpected transport [%i]",transport); return NULL; @@ -38,10 +38,10 @@ const char* sal_transport_to_string(SalTransport transport) { } } SalTransport sal_transport_parse(const char* param) { - if (strcasecmp("UDP",param)==0) return SalTransportUDP; - if (strcasecmp("TCP",param)==0) return SalTransportTCP; - if (strcasecmp("TLS",param)==0) return SalTransportTLS; - if (strcasecmp("DTLS",param)==0) return SalTransportDTLS; + if (strcasecmp("udp",param)==0) return SalTransportUDP; + if (strcasecmp("tcp",param)==0) return SalTransportTCP; + if (strcasecmp("tls",param)==0) return SalTransportTLS; + if (strcasecmp("dtls",param)==0) return SalTransportDTLS; ms_error("Unkown transport type[%s], returning UDP", param); return SalTransportUDP; } diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 7c04454b4..7df0fc385 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -362,6 +362,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive); break; case SalTransportTCP: + case SalTransportTLS: proto= IPPROTO_TCP; keepalive=-1; eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); @@ -382,11 +383,11 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i ipv6=strchr(addr,':')!=NULL; eXosip_enable_ipv6(ipv6); - if (is_secure){ - ms_fatal("SIP over TLS or DTLS is not supported yet."); + if (is_secure && tr == SalTransportUDP){ + ms_fatal("SIP over DTLS is not supported yet."); return -1; } - err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0); + err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure); #ifdef HAVE_EXOSIP_GET_SOCKET ms_message("Exosip has socket number %i",eXosip_get_socket(proto)); #endif From a1f54297c7700ff80c20af25492115c3e26ed2fa Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 20 Jul 2011 12:03:59 +0200 Subject: [PATCH 36/51] android: always build libssl and libcrypto --- build/android/Android.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index 7c9d13491..77e2d502d 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -114,7 +114,6 @@ LOCAL_SHARED_LIBRARIES += \ libavutil endif - LOCAL_STATIC_LIBRARIES += libspeex @@ -128,6 +127,8 @@ LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +LOCAL_SHARED_LIBRARIES += \ + liblinssl liblincrypto ifeq ($(BUILD_GPLV3_ZRTP),1) LOCAL_SHARED_LIBRARIES += \ libzrtpcpp @@ -137,6 +138,9 @@ ifeq ($(BUILD_SRTP),1) LOCAL_SHARED_LIBRARIES += \ libsrtp endif +else +LOCAL_STATIC_LIBRARIES += \ + libssl-static libcrypto-static endif LOCAL_MODULE := liblinphone From 11aeb96df5920cebbc95584ac17cb709cba37a8f Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Wed, 20 Jul 2011 15:28:54 +0200 Subject: [PATCH 37/51] android: update build file (libssl enabled) --- build/android/Android.mk | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index 77e2d502d..817ed9155 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -127,20 +127,22 @@ LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) -LOCAL_SHARED_LIBRARIES += \ - liblinssl liblincrypto -ifeq ($(BUILD_GPLV3_ZRTP),1) -LOCAL_SHARED_LIBRARIES += \ - libzrtpcpp -endif + LOCAL_SHARED_LIBRARIES += \ + liblinssl liblincrypto + ifeq ($(BUILD_GPLV3_ZRTP),1) + LOCAL_SHARED_LIBRARIES += \ + libzrtpcpp + endif -ifeq ($(BUILD_SRTP),1) -LOCAL_SHARED_LIBRARIES += \ - libsrtp -endif + ifeq ($(BUILD_SRTP),1) + LOCAL_SHARED_LIBRARIES += \ + libsrtp + endif else -LOCAL_STATIC_LIBRARIES += \ - libssl-static libcrypto-static + LOCAL_LDLIBS += -lz + #LOCAL_STATIC_LIBRARIES += libz libdl + LOCAL_STATIC_LIBRARIES += \ + libssl-static libcrypto-static endif LOCAL_MODULE := liblinphone From b0e75d9d78307802a540ca1cf611d47392ebfc99 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 22 Jul 2011 11:37:38 +0200 Subject: [PATCH 38/51] Add configuration option allowing to specify trusted CA certificates. This option can contain either : - a single file path; this file can contain several concatenated CA PEM files - a folder path containing several CA PEM files --- coreapi/linphonecore.c | 14 ++++++++++++++ coreapi/linphonecore.h | 1 + coreapi/linphonecore_jni.cc | 8 ++++++++ coreapi/sal.h | 1 + coreapi/sal_eXosip2.c | 19 ++++++++++++++++++- coreapi/sal_eXosip2.h | 1 + .../org/linphone/core/LinphoneCore.java | 8 ++++++++ 7 files changed, 51 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 847316d07..0db1485f3 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -514,6 +514,8 @@ static void sip_config_read(LinphoneCore *lc) ms_free(contact); } + sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs")); + tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1); linphone_core_set_guess_hostname(lc,tmp); @@ -2898,6 +2900,18 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){ return lc->sound_conf.local_ring; } +/** + * Sets the path to a file or folder containing trusted root CAs (PEM format) + * + * @param path + * @param lc The LinphoneCore object + * + * @ingroup media_parameters +**/ +void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){ + sal_root_ca(lc->sal, path); +} + static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){ LinphoneCore *lc=(LinphoneCore*)ud; lc->preview_finished=1; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 3d263082d..010b15851 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -857,6 +857,7 @@ char linphone_core_get_sound_source(LinphoneCore *lc); void linphone_core_set_sound_source(LinphoneCore *lc, char source); void linphone_core_set_ring(LinphoneCore *lc, const char *path); const char *linphone_core_get_ring(const LinphoneCore *lc); +void linphone_core_set_root_ca(LinphoneCore *lc, const char *path); void linphone_core_set_ringback(LinphoneCore *lc, const char *path); const char * linphone_core_get_ringback(const LinphoneCore *lc); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 1f200c82f..823e5e44f 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -698,6 +698,14 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env return NULL; } } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setRootCA(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jstring jpath) { + const char* path = jpath?env->GetStringUTFChars(jpath, NULL):NULL; + linphone_core_set_root_ca((LinphoneCore*)lc,path); + if (path) env->ReleaseStringUTFChars(jpath, path); +} extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableKeepAlive(JNIEnv* env ,jobject thiz ,jlong lc diff --git a/coreapi/sal.h b/coreapi/sal.h index 47286b09c..01bf3c71a 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -276,6 +276,7 @@ void sal_reuse_authorization(Sal *ctx, bool_t enabled); void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec); void sal_use_rport(Sal *ctx, bool_t use_rports); void sal_use_101(Sal *ctx, bool_t use_101); +void sal_root_ca(Sal* ctx, const char* rootCa); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 7df0fc385..ff078ccf8 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -281,11 +281,14 @@ Sal * sal_init(){ sal->use_rports=TRUE; sal->use_101=TRUE; sal->reuse_authorization=FALSE; + sal->rootCa = 0; return sal; } void sal_uninit(Sal* sal){ eXosip_quit(); + if (sal->rootCa) + ms_free(sal->rootCa); ms_free(sal); } @@ -365,7 +368,14 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i case SalTransportTLS: proto= IPPROTO_TCP; keepalive=-1; - eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); + eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); + + if (ctx->rootCa) { + eXosip_tls_ctx_t tlsCtx; + memset(&tlsCtx, 0, sizeof(tlsCtx)); + snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa); + eXosip_set_tls_ctx(&tlsCtx); + } break; default: ms_warning("unexpected proto, using datagram"); @@ -432,6 +442,13 @@ void sal_use_101(Sal *ctx, bool_t use_101){ ctx->use_101=use_101; } +void sal_root_ca(Sal* ctx, const char* rootCa) { + if (ctx->rootCa) + ms_free(ctx->rootCa); + ctx->rootCa = ms_strdup(rootCa); + ms_error("YIPI : %s == %s\n", rootCa, ctx->rootCa); +} + static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ osip_via_t *via=NULL; osip_generic_param_t *param=NULL; diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 201cb65a9..bdc257740 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -45,6 +45,7 @@ struct Sal{ bool_t use_rports; bool_t use_101; bool_t reuse_authorization; + char* rootCa; /* File _or_ folder containing root CA */ }; struct SalOp{ diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index bb52cc874..91f056c23 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -528,6 +528,14 @@ public interface LinphoneCore { * @param null if not set */ String getRing(); + + /** + * Sets file or folder containing trusted root CAs + * + * @param path path to file with multiple PEM certif or to folder with multiple PEM files + */ + void setRootCA(String path); + void setUploadBandwidth(int bw); void setDownloadBandwidth(int bw); From 393a70252c8c69602a7754037ac690428de080bd Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 22 Jul 2011 12:22:55 +0200 Subject: [PATCH 39/51] Removed debug trace --- coreapi/sal_eXosip2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index ff078ccf8..389179008 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -446,7 +446,6 @@ void sal_root_ca(Sal* ctx, const char* rootCa) { if (ctx->rootCa) ms_free(ctx->rootCa); ctx->rootCa = ms_strdup(rootCa); - ms_error("YIPI : %s == %s\n", rootCa, ctx->rootCa); } static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ From 00d09892c7b60804a3f3cbcbe66d61a23d6f779c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 29 Jul 2011 16:19:31 +0200 Subject: [PATCH 40/51] fix exosip2 version requirement --- m4/exosip.m4 | 4 ++-- mediastreamer2 | 2 +- oRTP | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/m4/exosip.m4 b/m4/exosip.m4 index cf1db587d..2c21b129d 100644 --- a/m4/exosip.m4 +++ b/m4/exosip.m4 @@ -25,9 +25,9 @@ dnl check for eXosip2 libs LDFLAGS_save=$LDFLAGS LDFLAGS="$OSIP_LIBS $LDFLAGS $OPENSSL_LIBS" LIBS_save=$LIBS -AC_CHECK_LIB([eXosip2],[eXosip_subscribe_remove], +AC_CHECK_LIB([eXosip2],[eXosip_set_tls_ctx], [], - [AC_MSG_ERROR([Could not find eXosip2 library with version >= 3.0.2 !])], + [AC_MSG_ERROR([Could not find eXosip2 library with version >= 3.5.0 !])], [-losipparser2 -losip2 ]) AC_CHECK_LIB([eXosip2],[eXosip_get_version], [AC_DEFINE([HAVE_EXOSIP_GET_VERSION],[1],[Defined when eXosip_get_version is available])], diff --git a/mediastreamer2 b/mediastreamer2 index 909125059..1b8cb2902 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9091250591e54e6533cea8ba8c203f6f4f47550d +Subproject commit 1b8cb2902a0ee26327cbf8db2d8185bcce2d74a6 diff --git a/oRTP b/oRTP index 9cdfa6c82..44c5fb07f 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 9cdfa6c826b2a2701122a50ed3c78afa8ef17ec6 +Subproject commit 44c5fb07fe3b3e2648eda7a63d7e997ccf6b0c11 From a2699e54294837654ac59de021a70372e6529c81 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Mon, 1 Aug 2011 11:48:26 +0200 Subject: [PATCH 41/51] Simplified ORTP-ZRTP API. Fix SAS bubbling. Old ARMs --- build/android/Android.mk | 16 ++++++++------ coreapi/linphonecall.c | 42 ++++++++++++++++++++++++++----------- coreapi/linphonecore_jni.cc | 26 +++++++++++------------ mediastreamer2 | 2 +- oRTP | 2 +- 5 files changed, 55 insertions(+), 33 deletions(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index 817ed9155..dcc9c9fa6 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -127,22 +127,26 @@ LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) - LOCAL_SHARED_LIBRARIES += \ - liblinssl liblincrypto + LOCAL_SHARED_LIBRARIES += liblinssl liblincrypto ifeq ($(BUILD_GPLV3_ZRTP),1) - LOCAL_SHARED_LIBRARIES += \ - libzrtpcpp + LOCAL_SHARED_LIBRARIES += libzrtpcpp endif ifeq ($(BUILD_SRTP),1) - LOCAL_SHARED_LIBRARIES += \ - libsrtp + LOCAL_SHARED_LIBRARIES += libsrtp endif else LOCAL_LDLIBS += -lz #LOCAL_STATIC_LIBRARIES += libz libdl LOCAL_STATIC_LIBRARIES += \ libssl-static libcrypto-static + ifeq ($(BUILD_GPLV3_ZRTP),1) + LOCAL_STATIC_LIBRARIES += libzrtpcpp-static + endif + + ifeq ($(BUILD_SRTP),1) + LOCAL_STATIC_LIBRARIES += libsrtp-static + endif endif LOCAL_MODULE := liblinphone diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7f9c12c20..f405c139a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -79,7 +79,7 @@ bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) { return TRUE; } -static void propagate_encryption_changed(LinphoneCall *call){ +void propagate_encryption_changed(LinphoneCall *call){ if (call->core->vtable.call_encryption_changed == NULL) return; if (!linphone_call_are_all_streams_encrypted(call)) { @@ -115,10 +115,6 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr OrtpZrtpParams params; params.zid=get_zrtp_identifier(call->core); params.zid_file=NULL; //unused - OrtpZrtpUiCb cbs={0}; - cbs.data=call; - cbs.encryption_changed=linphone_call_videostream_encryption_changed; - params.ui_cbs=&cbs; video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms); } #endif @@ -1117,11 +1113,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut OrtpZrtpParams params; params.zid=get_zrtp_identifier(lc); params.zid_file=lc->zrtp_secrets_cache; - OrtpZrtpUiCb cbs={0}; - cbs.data=call; - cbs.encryption_changed=linphone_call_audiostream_encryption_changed; - cbs.sas_ready=linphone_call_audiostream_auth_token_ready; - params.ui_cbs=&cbs; audio_stream_enable_zrtp(call->audiostream,¶ms); } @@ -1333,11 +1324,38 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load); } #ifdef VIDEO_ENABLED - if (call->videostream!=NULL) + if (call->videostream!=NULL) { + if (call->videostream->evq){ + OrtpEvent *ev=ortp_ev_queue_get(call->videostream->evq); + if (ev!=NULL){ + OrtpEventType evt=ortp_event_get_type(ev); + if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); + } + ortp_event_destroy(ev); + } + } video_stream_iterate(call->videostream); + } #endif - if (call->audiostream!=NULL) + if (call->audiostream!=NULL) { + if (call->audiostream->evq){ + OrtpEvent *ev=ortp_ev_queue_get(call->audiostream->evq); + if (ev!=NULL){ + OrtpEventType evt=ortp_event_get_type(ev); + if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); + } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) { + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified); + } + ortp_event_destroy(ev); + } + } audio_stream_iterate(call->audiostream); + } if (one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 ) disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout); if (disconnected) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 823e5e44f..35cade522 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -90,47 +90,47 @@ public: vTable.global_state_changed = globalStateChange; vTable.registration_state_changed = registrationStateChange; vTable.call_state_changed = callStateChange; - //vTable.call_encryption_changed = callEncryptionChange; + vTable.call_encryption_changed = callEncryptionChange; vTable.text_received = text_received; vTable.new_subscription_request = new_subscription_request; vTable.notify_presence_recv = notify_presence_recv; - listernerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); + listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); /*displayStatus(LinphoneCore lc,String message);*/ - displayStatusId = env->GetMethodID(listernerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); + displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); /*void generalState(LinphoneCore lc,int state); */ - globalStateId = env->GetMethodID(listernerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); + globalStateId = env->GetMethodID(listenerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState")); globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;"); /*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/ - registrationStateId = env->GetMethodID(listernerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); + registrationStateId = env->GetMethodID(listenerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState")); registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;"); /*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/ - callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); + callStateId = env->GetMethodID(listenerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State")); callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ - callEncryptionChangedId=env->GetMethodID(listernerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); + callEncryptionChangedId=env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); /*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/ - ecCalibrationStatusId = env->GetMethodID(listernerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V"); + ecCalibrationStatusId = env->GetMethodID(listenerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V"); ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus")); ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;"); /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ - newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); + newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); /*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/ - notifyPresenceReceivedId = env->GetMethodID(listernerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); + notifyPresenceReceivedId = env->GetMethodID(listenerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); /*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/ - textReceivedId = env->GetMethodID(listernerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); + textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); proxyCtrId = env->GetMethodID(proxyClass,"", "(J)V"); @@ -155,7 +155,7 @@ public: env->DeleteGlobalRef(core); env->DeleteGlobalRef(listener); if (userdata) env->DeleteGlobalRef(userdata); - env->DeleteGlobalRef(listernerClass); + env->DeleteGlobalRef(listenerClass); env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(registrationStateClass); env->DeleteGlobalRef(callStateClass); @@ -169,7 +169,7 @@ public: jobject listener; jobject userdata; - jclass listernerClass; + jclass listenerClass; jmethodID displayStatusId; jmethodID newSubscriptionRequestId; jmethodID notifyPresenceReceivedId; diff --git a/mediastreamer2 b/mediastreamer2 index 909125059..97b4a85bb 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9091250591e54e6533cea8ba8c203f6f4f47550d +Subproject commit 97b4a85bba7b0c75040137b6ba1a3543fda9c63c diff --git a/oRTP b/oRTP index 9cdfa6c82..e3e56ecd6 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 9cdfa6c826b2a2701122a50ed3c78afa8ef17ec6 +Subproject commit e3e56ecd6179085ffeaf70482da4571415e3e5ff From d8adfcf296d72a2a755779a090fd04f6d60e26a8 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Tue, 2 Aug 2011 11:36:10 +0200 Subject: [PATCH 42/51] Move ZRTP flags to application level. --- console/linphonec.c | 5 ++-- coreapi/linphonecall.c | 65 ++++++++++++++++++++++++++++++------------ coreapi/private.h | 6 ++++ mediastreamer2 | 2 +- 4 files changed, 56 insertions(+), 22 deletions(-) diff --git a/console/linphonec.c b/console/linphonec.c index fef795d86..f4d855574 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -326,9 +326,10 @@ static void linphonec_call_updated(LinphoneCall *call){ static void linphonec_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t encrypted, const char *auth_token) { long id=(long)linphone_call_get_user_pointer (call); if (!encrypted) { - linphonec_out("Call %i is not encrypted.\n", id); + linphonec_out("Call %i is not fully encrypted and auth token is %s.\n", id, + (auth_token != NULL) ? auth_token : "absent"); } else { - linphonec_out("Call %i is encrypted and auth token is %s.\n", id, + linphonec_out("Call %i is fully encrypted and auth token is %s.\n", id, (auth_token != NULL) ? auth_token : "absent"); } } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index f405c139a..ee69c93dc 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sipsetup.h" #include "lpconfig.h" #include "private.h" +#include #include "mediastreamer2/mediastream.h" @@ -56,22 +57,22 @@ static const char* get_zrtp_identifier(LinphoneCore *lc){ } const char* linphone_call_get_authentication_token(LinphoneCall *call){ - return call->audiostream->auth_token; + return call->auth_token; } bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){ - return call->audiostream->auth_token_verified; + return call->auth_token_verified; } bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) { // Check ZRTP encryption in audiostream - if (!call->audiostream->encrypted) { + if (!call->audiostream_encrypted) { return FALSE; } #ifdef VIDEO_ENABLED // If video enabled, check ZRTP encryption in videostream const LinphoneCallParams *params=linphone_call_get_current_params(call); - if (params->has_video && !call->videostream->encrypted) { + if (params->has_video && !call->videostream_encrypted) { return FALSE; } #endif @@ -83,9 +84,11 @@ void propagate_encryption_changed(LinphoneCall *call){ if (call->core->vtable.call_encryption_changed == NULL) return; if (!linphone_call_are_all_streams_encrypted(call)) { - call->core->vtable.call_encryption_changed(call->core, call, FALSE, NULL); + ms_message("Some streams are not encrypted"); + call->core->vtable.call_encryption_changed(call->core, call, FALSE, call->auth_token); } else { - call->core->vtable.call_encryption_changed(call->core, call, TRUE, call->audiostream->auth_token); + ms_message("All streams are encrypted"); + call->core->vtable.call_encryption_changed(call->core, call, TRUE, call->auth_token); } } @@ -94,7 +97,7 @@ static void linphone_call_videostream_encryption_changed(void *data, bool_t encr ms_message("Video stream is %s", encrypted ? "encrypted" : "not encrypted"); LinphoneCall *call = (LinphoneCall *)data; - call->videostream->encrypted=encrypted; + call->videostream_encrypted=encrypted; propagate_encryption_changed(call); } #endif @@ -103,7 +106,7 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr ms_message("Audio stream is %s ", encrypted ? "encrypted" : "not encrypted"); LinphoneCall *call = (LinphoneCall *)data; - call->audiostream->encrypted=encrypted; + call->audiostream_encrypted=encrypted; propagate_encryption_changed(call); @@ -123,11 +126,11 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr static void linphone_call_audiostream_auth_token_ready(void *data, const char* auth_token, bool_t verified) { LinphoneCall *call=(LinphoneCall *)data; - if (call->audiostream->auth_token != NULL) - ms_free(call->audiostream->auth_token); + if (call->auth_token != NULL) + ms_free(call->auth_token); - call->audiostream->auth_token=ms_strdup(auth_token); - call->audiostream->auth_token_verified=verified; + call->auth_token=ms_strdup(auth_token); + call->auth_token_verified=verified; ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified"); } @@ -449,6 +452,10 @@ static void linphone_call_destroy(LinphoneCall *obj) } if (obj->owns_call_log) linphone_call_log_destroy(obj->log); + if (obj->auth_token) { + ms_free(obj->auth_token); + } + ms_free(obj); } @@ -765,6 +772,9 @@ void linphone_call_init_media_streams(LinphoneCall *call){ if (lc->a_rtp) rtp_session_set_transports(audiostream->session,lc->a_rtp,lc->a_rtcp); + call->audiostream_app_evq = ortp_ev_queue_new(); + rtp_session_register_event_queue(audiostream->session,call->audiostream_app_evq); + #ifdef VIDEO_ENABLED if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].port>0){ @@ -774,6 +784,8 @@ void linphone_call_init_media_streams(LinphoneCall *call){ video_stream_set_event_callback(call->videostream,video_stream_event_cb, call); if (lc->v_rtp) rtp_session_set_transports(call->videostream->session,lc->v_rtp,lc->v_rtcp); + call->videostream_app_evq = ortp_ev_queue_new(); + rtp_session_register_event_queue(call->videostream->session,call->videostream_app_evq); #ifdef TEST_EXT_RENDERER video_stream_set_render_callback(call->videostream,rendercb,NULL); #endif @@ -1129,6 +1141,10 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){ void linphone_call_stop_media_streams(LinphoneCall *call){ if (call->audiostream!=NULL) { + rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq); + ortp_ev_queue_flush(call->audiostream_app_evq); + ortp_ev_queue_destroy(call->audiostream_app_evq); + if (call->audiostream->ec){ const char *state_str=NULL; ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_GET_STATE_STRING,&state_str); @@ -1141,8 +1157,13 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ audio_stream_stop(call->audiostream); call->audiostream=NULL; } + + #ifdef VIDEO_ENABLED if (call->videostream!=NULL){ + rtp_session_unregister_event_queue(call->videostream->session,call->videostream_app_evq); + ortp_ev_queue_flush(call->videostream_app_evq); + ortp_ev_queue_destroy(call->videostream_app_evq); video_stream_stop(call->videostream); call->videostream=NULL; } @@ -1325,9 +1346,13 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse } #ifdef VIDEO_ENABLED if (call->videostream!=NULL) { - if (call->videostream->evq){ - OrtpEvent *ev=ortp_ev_queue_get(call->videostream->evq); - if (ev!=NULL){ + // Beware that the application queue should not depend on treatments fron the + // mediastreamer queue. + video_stream_iterate(call->videostream); + + if (call->videostream_app_evq){ + OrtpEvent *ev; + while (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq))){ OrtpEventType evt=ortp_event_get_type(ev); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ OrtpEventData *evd=ortp_event_get_data(ev); @@ -1336,13 +1361,16 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse ortp_event_destroy(ev); } } - video_stream_iterate(call->videostream); } #endif if (call->audiostream!=NULL) { + // Beware that the application queue should not depend on treatments fron the + // mediastreamer queue. + audio_stream_iterate(call->audiostream); + if (call->audiostream->evq){ - OrtpEvent *ev=ortp_ev_queue_get(call->audiostream->evq); - if (ev!=NULL){ + OrtpEvent *ev; + while (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq))){ OrtpEventType evt=ortp_event_get_type(ev); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ OrtpEventData *evd=ortp_event_get_data(ev); @@ -1354,7 +1382,6 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse ortp_event_destroy(ev); } } - audio_stream_iterate(call->audiostream); } if (one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 ) disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout); diff --git a/coreapi/private.h b/coreapi/private.h index 7fd8f1934..e79780b91 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -99,6 +99,12 @@ struct _LinphoneCall bool_t all_muted; /*this flag is set during early medias*/ bool_t playing_ringbacktone; bool_t owns_call_log; + OrtpEvQueue *audiostream_app_evq; + bool_t audiostream_encrypted; + char *auth_token; + bool_t auth_token_verified; + OrtpEvQueue *videostream_app_evq; + bool_t videostream_encrypted; }; diff --git a/mediastreamer2 b/mediastreamer2 index 97b4a85bb..737846b37 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 97b4a85bba7b0c75040137b6ba1a3543fda9c63c +Subproject commit 737846b3719dd5be9786f2a9be1aacf29595ad9f From 743ef7d0cf511161ff4c2300315df775e601bae3 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 3 Aug 2011 12:45:50 +0200 Subject: [PATCH 43/51] Fix compilation issue. --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index 737846b37..2b7737db9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 737846b3719dd5be9786f2a9be1aacf29595ad9f +Subproject commit 2b7737db95eda8f971a65fd6408d098f23a0574d diff --git a/oRTP b/oRTP index e3e56ecd6..536ad766c 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit e3e56ecd6179085ffeaf70482da4571415e3e5ff +Subproject commit 536ad766cf13da4115c456170afee96113de533f From f421522c5f5bf20327c38842a8370d93b3f3b38f Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 4 Aug 2011 12:45:04 +0200 Subject: [PATCH 44/51] vp8: add vp8 payload assignation to linphone --- coreapi/linphonecore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0db1485f3..0d7a33ccc 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -992,6 +992,7 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta linphone_core_assign_payload_type(&payload_type_mp4v,99,"profile-level-id=3"); linphone_core_assign_payload_type(&payload_type_x_snow,100,NULL); linphone_core_assign_payload_type(&payload_type_h264,102,"profile-level-id=428014"); + linphone_core_assign_payload_type(&payload_type_vp8,103,NULL); /* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */ /* linphone_core_assign_payload_type(&payload_type_h264,103,"packetization-mode=1;profile-level-id=428014");*/ #endif From a0b9b02506a8a4eb97f7eb44e376ea1999e4bd9b Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Thu, 4 Aug 2011 12:52:31 +0200 Subject: [PATCH 45/51] Updated mediastreamer2 version --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 2b7737db9..813dd63dc 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2b7737db95eda8f971a65fd6408d098f23a0574d +Subproject commit 813dd63dc151d4202c3f52f3eab9f6d880bfc19b From 68df42b2924930043bbf466b0c6eab1409fb6c3e Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 5 Aug 2011 16:11:35 +0200 Subject: [PATCH 46/51] Hack to workaround Galaxy S speaker/mic issue (Android) --- coreapi/linphonecore_jni.cc | 10 ++++++++++ mediastreamer2 | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 35cade522..349efb02c 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1341,3 +1341,13 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isAuthenticationToke extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_areStreamsEncrypted(JNIEnv* env,jobject thiz,jlong ptr) { return linphone_call_are_all_streams_encrypted((LinphoneCall *) ptr); } + +// Needed by Galaxy S (can't switch to/from speaker while playing and still keep mic working) +// Implemented directly in msandroid.cpp (sound filters for Android). +extern "C" void msandroid_hack_speaker_state(bool speakerOn); + +extern "C" void Java_org_linphone_LinphoneManager_hackSpeakerState(JNIEnv* env,jobject thiz,jboolean speakerOn){ + msandroid_hack_speaker_state(speakerOn); +// End Galaxy S hack functions +} + diff --git a/mediastreamer2 b/mediastreamer2 index 813dd63dc..57319ab67 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 813dd63dc151d4202c3f52f3eab9f6d880bfc19b +Subproject commit 57319ab677c00e43b576b4204df870074a9216f6 From d22b1c0447e4a381f4d0b9d60253c0d32c785964 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 8 Aug 2011 17:11:20 +0200 Subject: [PATCH 47/51] merge patch to adjust software gain from console app --- console/commands.c | 12 ++++++++++++ mediastreamer2 | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/console/commands.c b/console/commands.c index 867e4b867..32482bad7 100644 --- a/console/commands.c +++ b/console/commands.c @@ -90,6 +90,7 @@ static int lpc_cmd_pause(LinphoneCore *lc, char *args); static int lpc_cmd_resume(LinphoneCore *lc, char *args); static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args); static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args); +static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args); static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args); #ifdef VIDEO_ENABLED static int lpc_cmd_camera(LinphoneCore *lc, char *args); @@ -192,6 +193,8 @@ static LPC_COMMAND commands[] = { #endif { "unmute", lpc_cmd_unmute_mic, "Unmute microphone and resume voice transmission."}, + { "playbackgain", lpc_cmd_playback_gain, + "Adjust playback gain."}, { "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL }, { "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode", @@ -2303,6 +2306,15 @@ static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args){ return 1; } +static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args) +{ + if (args){ + linphone_core_set_playback_gain_db(lc, atof(args)); + return 1; + } + return 0; +} + static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args) { bool_t rtp_xmit_off=FALSE; diff --git a/mediastreamer2 b/mediastreamer2 index 57319ab67..c2ec52b09 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 57319ab677c00e43b576b4204df870074a9216f6 +Subproject commit c2ec52b097ec3165cbfb2b93dc788383612e1569 From 612f0cf326f4d2c3abdb5cd6d7967b918a2ef7ac Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Tue, 9 Aug 2011 16:51:55 +0200 Subject: [PATCH 48/51] android: vp8 integration --- build/android/Android.mk | 3 ++- mediastreamer2 | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index dcc9c9fa6..8d72eb222 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -102,10 +102,11 @@ LOCAL_STATIC_LIBRARIES += \ endif ifeq ($(LINPHONE_VIDEO),1) +LOCAL_STATIC_LIBRARIES += libvpx ifeq ($(BUILD_X264),1) LOCAL_STATIC_LIBRARIES += \ libmsx264 \ - libx264 + libx264 endif LOCAL_SHARED_LIBRARIES += \ libavcodec \ diff --git a/mediastreamer2 b/mediastreamer2 index c2ec52b09..9300335bb 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c2ec52b097ec3165cbfb2b93dc788383612e1569 +Subproject commit 9300335bbb536c4e67961c9c0b6b6b013fc4e8ff From be98d6653e167827834af723a963dec8bcc96fa3 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 10 Aug 2011 21:48:03 +0200 Subject: [PATCH 49/51] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 9300335bb..79ad12c76 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9300335bbb536c4e67961c9c0b6b6b013fc4e8ff +Subproject commit 79ad12c768fbbc672e43975ef3107459649e742e From 6cb384bf83b8233666d55ecb517939340632f78b Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 12 Aug 2011 09:39:12 +0200 Subject: [PATCH 50/51] add opengl libs --- build/android/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/build/android/Android.mk b/build/android/Android.mk index 8d72eb222..28878a5bc 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -127,6 +127,7 @@ LOCAL_SRC_FILES += $(LIBLINPHONE_EXTENDED_SRC_FILES) LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif +LOCAL_LDLIBS += -lGLESv2 ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_SHARED_LIBRARIES += liblinssl liblincrypto ifeq ($(BUILD_GPLV3_ZRTP),1) From 5162f7f922b3b66399ecb325ddc858a6fbeb9d19 Mon Sep 17 00:00:00 2001 From: Pierre-Eric Pelloux-Prayer Date: Fri, 12 Aug 2011 15:48:50 +0200 Subject: [PATCH 51/51] Update mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 9300335bb..548c70123 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9300335bbb536c4e67961c9c0b6b6b013fc4e8ff +Subproject commit 548c7012382db6442a2ec75f4d9ff8f67c853244