From bc8f026d2b9a8c058f1411037f397a96d422c107 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Thu, 31 May 2012 14:15:17 +0200 Subject: [PATCH 01/19] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 8fb5d72cf..38d2d7411 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 8fb5d72cf1ecc1c30c29fc4ba093b9bade74ba6a +Subproject commit 38d2d7411a6fb3cd61d33234a16b88ade1967b4d From 3d0d30a5ae0cd5e6d910d77d1f2b11e93a290757 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 31 May 2012 15:32:07 +0200 Subject: [PATCH 02/19] update README and improve windows logging --- README.mingw | 26 ++++++++++++++++++++++---- gtk/logging.c | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/README.mingw b/README.mingw index c35236dcc..42b130f33 100644 --- a/README.mingw +++ b/README.mingw @@ -26,7 +26,7 @@ Download lastest linphone-deps-win32 zip from http://download.savannah.gnu.org/releases-noredirect/linphone/misc using your browser. -Download lastest gtk+ win32 bundle from http://www.gtk.org +Download lastest gtk+2 win32 bundle from http://www.gtk.org Install all these three package in /: @@ -65,20 +65,38 @@ WARNING: During the build, windows might slow down suddenly. Using ctl+alt+del t you might see a process 'LVpSRV.exe' or something like this that eats 90% of cpu. Kill it. Don't know what it is, but once killed, windows runs normally. -#Compile and install tunnel -cd tunnel && ./autogen.sh && ./configure --prefix=/opt/linphone && make && make install +#Compile and install tunnel (optional, available under proprietary licensing) + +cd tunnel && ./autogen.sh && ./configure --prefix=/usr --enable-shared --disable-static && make && make install + +#Build linphone itself: #run autogen.sh after a git checkout or update + ./autogen.sh + ./configure --prefix=/opt/linphone --enable-shared --disable-static +#note: in order to use the tunnel, append --enable-tunnel to the configure line above. + +#compile: + make -#will install to /opt/linphone, required for compilation of plugins. + +#now install to /opt/linphone, required for compilation of plugins. + make install + #make a binary zip of linphone + make zip + #additionally you can make binary installer if you have Inno Setup 5 installed in its default path + make setup.exe + #now you're done, you have a fresh linphone windows installer in the current directory. + + #build plugins cd mediastreamer2/plugins/msx264 ./autogen.sh diff --git a/gtk/logging.c b/gtk/logging.c index e2a9da600..15bef85e0 100644 --- a/gtk/logging.c +++ b/gtk/logging.c @@ -206,6 +206,7 @@ static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg) case of a crash (which is one of the main reasons we have a log facility in the first place). */ fprintf(outlog, "[%s] [%s] %s\n", date, lname, msg); + fflush(outlog); } } From d3d00b7ef2dfb412bf4e316e276899ff82c39975 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 1 Jun 2012 14:46:58 +0200 Subject: [PATCH 03/19] add --no-video option to gtk app --- gtk/main.c | 29 ++++++++++++++++++++++------- mediastreamer2 | 2 +- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/gtk/main.c b/gtk/main.c index fc8a6bfcc..2a6c307b6 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -18,7 +18,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define VIDEOSELFVIEW_DEFAULT 1 +#define VIDEOSELFVIEW_DEFAULT 0 #include "linphone.h" #include "lpconfig.h" @@ -66,11 +66,13 @@ static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate); static gboolean linphone_gtk_auto_answer(LinphoneCall *call); static void linphone_gtk_status_icon_set_blinking(gboolean val); +void _linphone_gtk_enable_video(gboolean val); static gboolean verbose=0; static gboolean auto_answer = 0; static gchar * addr_to_call = NULL; +static gboolean no_video=FALSE; static gboolean iconified=FALSE; static gchar *workingdir=NULL; static char *progpath=NULL; @@ -91,6 +93,13 @@ static GOptionEntry linphone_options[]={ .arg_data = &linphone_logfile, .description = N_("path to a file to write logs into.") }, + { + .long_name = "no-video", + .short_name = '\0', + .arg = G_OPTION_ARG_NONE, + .arg_data = (gpointer)&no_video, + .description = N_("Start linphone with video disabled.") + }, { .long_name="iconified", .short_name= '\0', @@ -234,6 +243,10 @@ static void linphone_gtk_init_liblinphone(const char *config_file, linphone_core_set_zrtp_secrets_file(the_core,secrets_file); g_free(secrets_file); linphone_core_enable_video(the_core,TRUE,TRUE); + if (no_video) { + _linphone_gtk_enable_video(FALSE); + linphone_gtk_set_ui_config_int("videoselfview",0); + } } @@ -648,10 +661,8 @@ bool_t linphone_gtk_video_enabled(void){ void linphone_gtk_show_main_window(){ GtkWidget *w=linphone_gtk_get_main_window(); LinphoneCore *lc=linphone_gtk_get_core(); - if (linphone_gtk_video_enabled()){ - linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview", + linphone_core_enable_video_preview(lc,linphone_gtk_get_ui_config_int("videoselfview", VIDEOSELFVIEW_DEFAULT)); - } gtk_widget_show(w); gtk_window_present(GTK_WINDOW(w)); } @@ -772,9 +783,7 @@ void linphone_gtk_answer_clicked(GtkWidget *button){ } } -void linphone_gtk_enable_video(GtkWidget *w){ - gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); - //GtkWidget *selfview_item=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"selfview_item"); +void _linphone_gtk_enable_video(gboolean val){ LinphoneVideoPolicy policy={0}; policy.automatically_initiate=policy.automatically_accept=val; linphone_core_enable_video(linphone_gtk_get_core(),TRUE,TRUE); @@ -788,6 +797,12 @@ void linphone_gtk_enable_video(GtkWidget *w){ } } +void linphone_gtk_enable_video(GtkWidget *w){ + gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); + //GtkWidget *selfview_item=linphone_gtk_get_widget(linphone_gtk_get_main_window(),"selfview_item"); + _linphone_gtk_enable_video(val); +} + void linphone_gtk_enable_self_view(GtkWidget *w){ gboolean val=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w)); LinphoneCore *lc=linphone_gtk_get_core(); diff --git a/mediastreamer2 b/mediastreamer2 index 38d2d7411..343d9116b 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 38d2d7411a6fb3cd61d33234a16b88ade1967b4d +Subproject commit 343d9116b35e2f80c01e77a4bc7bbf898126cd53 From 31e817b49e39844029a7b1be5ae499cfd37b9a20 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 4 Jun 2012 12:23:37 +0200 Subject: [PATCH 04/19] workaround for SDP offers with zero ports --- coreapi/offeranswer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index fd0196782..5a2b4f527 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -233,7 +233,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, result->proto=remote_offer->proto; result->type=local_cap->type; result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir); - if (result->payloads && !only_telephone_event(result->payloads)){ + if (result->payloads && !only_telephone_event(result->payloads) && (remote_offer->port!=0 || remote_offer->port==SalStreamSendOnly)){ strcpy(result->addr,local_cap->addr); memcpy(result->candidates,local_cap->candidates,sizeof(result->candidates)); result->port=local_cap->port; From 2d669353c3eda22e63023fde2f3cde7b437d2c81 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 5 Jun 2012 12:54:33 +0200 Subject: [PATCH 05/19] fix unitialized value --- coreapi/sal_eXosip2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 7e48f02ca..4c0e5512b 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -162,7 +162,7 @@ void sal_exosip_fix_route(SalOp *op){ } SalOp * sal_op_new(Sal *sal){ - SalOp *op=ms_new(SalOp,1); + SalOp *op=ms_new0(SalOp,1); __sal_op_init(op,sal); op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1; op->result=NULL; From 3d5d12d8579996faf7d1ef8a2c600356c8d598ea Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 6 Jun 2012 10:50:15 +0200 Subject: [PATCH 06/19] implement expiration of old contact during double registration, and avoid sending an updated register if server already fixed the contact. --- coreapi/linphonecore.c | 1 + coreapi/sal.h | 1 + coreapi/sal_eXosip2.c | 67 +++++++++++++++++++++++++++++------------- coreapi/sal_eXosip2.h | 1 + 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 679f19604..77080eba8 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -478,6 +478,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)); + sal_expire_old_registration_contacts(lc->sal,lp_config_get_int(lc->config,"sip","expire_old_registration_contacts",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.h b/coreapi/sal.h index bbe4dafff..d2d9cbe51 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -291,6 +291,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_expire_old_registration_contacts(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); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 4c0e5512b..863c4f47b 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -33,7 +33,7 @@ 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 bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact); static void update_contact_from_response(SalOp *op, osip_message_t *response); void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){ @@ -283,6 +283,7 @@ Sal * sal_init(){ sal->reuse_authorization=FALSE; sal->rootCa = 0; sal->verify_server_certs=TRUE; + sal->expire_old_contact=FALSE; return sal; } @@ -429,6 +430,10 @@ void sal_use_double_registrations(Sal *ctx, bool_t enabled){ ctx->double_reg=enabled; } +void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){ + ctx->expire_old_contact=enabled; +} + void sal_use_rport(Sal *ctx, bool_t use_rports){ ctx->use_rports=use_rports; } @@ -1733,7 +1738,7 @@ 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 bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) { osip_contact_t *ctt=NULL; const char *received; int rport; @@ -1746,6 +1751,20 @@ static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_messag ms_warning("fix_message_contact(): no contact to update"); return FALSE; } + if (expire_last_contact){ + osip_contact_t *oldct=ctt; + osip_generic_param_t *param=NULL; + ctt=NULL; + osip_contact_clone(oldct,&ctt); + osip_list_add(&request->contacts,ctt,0); + osip_contact_param_get_byname(oldct,"expires",¶m); + if (param){ + if (param->gvalue) osip_free(param->gvalue); + param->gvalue=osip_strdup("0"); + }else{ + osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0")); + } + } if (ctt->url->host!=NULL){ osip_free(ctt->url->host); } @@ -1772,29 +1791,35 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori char* tmp; osip_message_t *msg=NULL; Sal* sal=op->base.root; + int i=0; + bool_t found_valid_contact=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(tmp); + do{ + ctt=NULL; + osip_message_get_contact(last_answer,i,&ctt); + if (ctt==NULL) osip_message_get_contact(orig_request,0,&ctt); + if (ctt){ + osip_contact_to_str(ctt,&tmp); + ori_contact_address = sal_address_new(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); - sal_address_destroy(ori_contact_address); - 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); + /*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 response has up to date contact, doing nothing."); + found_valid_contact=TRUE; + } + osip_free(tmp); + sal_address_destroy(ori_contact_address); + }else break; + i++; + }while(!found_valid_contact); + if (!found_valid_contact) + ms_message("Contact do not match, resending register."); + else return FALSE; eXosip_lock(); eXosip_register_build_register(op->rid,op->expires,&msg); @@ -1803,7 +1828,7 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori ms_warning("Fail to create a contact updated register."); return FALSE; } - if (fix_message_contact(op,msg,last_answer)) { + if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) { eXosip_register_send_register(op->rid,msg); eXosip_unlock(); ms_message("Resending new register with updated contact"); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index f85ddfa1c..ccc95d56a 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -47,6 +47,7 @@ struct Sal{ bool_t use_101; bool_t reuse_authorization; bool_t verify_server_certs; + bool_t expire_old_contact; }; struct SalOp{ From 903756a7cb30363efa6ad5a8285848fee3bacfd3 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 6 Jun 2012 21:48:29 +0200 Subject: [PATCH 07/19] fix possible infinite loop --- coreapi/sal_eXosip2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 863c4f47b..51cef8b66 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1800,7 +1800,7 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori do{ ctt=NULL; osip_message_get_contact(last_answer,i,&ctt); - if (ctt==NULL) osip_message_get_contact(orig_request,0,&ctt); + if (i==0 && ctt==NULL) osip_message_get_contact(orig_request,0,&ctt); if (ctt){ osip_contact_to_str(ctt,&tmp); ori_contact_address = sal_address_new(tmp); From c45873a06a7afa3fe0e011c365fea261339f4fba Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 7 Jun 2012 15:24:29 +0200 Subject: [PATCH 08/19] clean up expired contact in registrations --- coreapi/sal_eXosip2.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 51cef8b66..8333f1554 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1752,11 +1752,14 @@ static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_messag return FALSE; } if (expire_last_contact){ - osip_contact_t *oldct=ctt; + osip_contact_t *oldct=NULL,*prevct; osip_generic_param_t *param=NULL; - ctt=NULL; - osip_contact_clone(oldct,&ctt); - osip_list_add(&request->contacts,ctt,0); + osip_contact_clone(ctt,&oldct); + while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){ + osip_contact_free(prevct); + osip_list_remove(&request->contacts,1); + } + osip_list_add(&request->contacts,oldct,1); osip_contact_param_get_byname(oldct,"expires",¶m); if (param){ if (param->gvalue) osip_free(param->gvalue); @@ -1793,6 +1796,7 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori Sal* sal=op->base.root; int i=0; bool_t found_valid_contact=FALSE; + bool_t from_request=FALSE; if (sal->double_reg==FALSE ) return FALSE; @@ -1800,7 +1804,10 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori do{ ctt=NULL; osip_message_get_contact(last_answer,i,&ctt); - if (i==0 && ctt==NULL) osip_message_get_contact(orig_request,0,&ctt); + if (!from_request && ctt==NULL) { + osip_message_get_contact(orig_request,0,&ctt); + from_request=TRUE; + } if (ctt){ osip_contact_to_str(ctt,&tmp); ori_contact_address = sal_address_new(tmp); @@ -1809,7 +1816,12 @@ static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *ori 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 response has up to date contact, doing nothing."); + if (!from_request){ + ms_message("Register response has up to date contact, doing nothing."); + }else { + ms_warning("Register response does not have up to date contact, but last request had." + "Stupid registrar detected, giving up."); + } found_valid_contact=TRUE; } osip_free(tmp); From 71a3ba34641f32d3b069329b4eab56b10807ee42 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 12 Jun 2012 13:48:34 +0200 Subject: [PATCH 09/19] improve linphone_core_find_payload_type to use strcasecmp --- coreapi/linphonecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 77080eba8..19d6f1378 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4511,7 +4511,7 @@ static PayloadType* find_payload_type_from_list(const char* type, int rate,const const MSList *elem; for(elem=from;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; - if ((strcmp((char*)type, payload_type_get_mime(pt)) == 0) && (rate == -1 || rate==pt->clock_rate)) { + if ((strcasecmp((char*)type, payload_type_get_mime(pt)) == 0) && (rate == -1 || rate==pt->clock_rate)) { return pt; } } From 02130419d357a9148e87bf0bdcef3272f03740f4 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 12 Jun 2012 16:10:13 +0200 Subject: [PATCH 10/19] fix sip random port feature --- coreapi/linphonecore.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 19d6f1378..c0531ae9a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -467,6 +467,7 @@ static void sip_config_read(LinphoneCore *lc) LCSipTransports tr; int i,tmp; int ipv6; + int random_port; tmp=lp_config_get_int(lc->config,"sip","use_info",0); linphone_core_set_use_info_for_dtmf(lc,tmp); @@ -489,21 +490,26 @@ static void sip_config_read(LinphoneCore *lc) } linphone_core_enable_ipv6(lc,ipv6); memset(&tr,0,sizeof(tr)); - if (lp_config_get_int(lc->config,"sip","sip_random_port",0)) { - tr.udp_port=(0xDFF&+random())+1024; - } else { - tr.udp_port=lp_config_get_int(lc->config,"sip","sip_port",5060); - } - if (lp_config_get_int(lc->config,"sip","sip_tcp_random_port",0)) { - tr.tcp_port=(0xDFF&+random())+1024; - } 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); - } + + tr.udp_port=lp_config_get_int(lc->config,"sip","sip_port",0); + tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",0); + tr.tls_port=lp_config_get_int(lc->config,"sip","sip_tls_port",0); + + if (lp_config_get_int(lc->config,"sip","sip_random_port",0)==1) + random_port=(0xDFFF&random())+1024; + else random_port=0; + + if (tr.udp_port==0 && tr.tcp_port==0 && tr.tls_port==0){ + tr.udp_port=5060; + } + + if (tr.udp_port>0 && random_port){ + tr.udp_port=random_port; + }else if (tr.tcp_port>0 && random_port){ + tr.tcp_port=random_port; + }else if (tr.tls_port>0 && random_port){ + tr.tls_port=random_port; + } #ifdef __linux sal_set_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs")); From 3a4c17df8f5ac930894ffd3ac155d4d4dc0b40f5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 12 Jun 2012 16:18:19 +0200 Subject: [PATCH 11/19] Added getStatus method for LinphoneCallLog --- coreapi/linphonecore_jni.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 619961432..52f5d24ad 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1119,6 +1119,11 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallLogImpl_getFrom(JNIEnv* env ,jlong ptr) { return (jlong)((LinphoneCallLog*)ptr)->from; } +extern "C" int Java_org_linphone_core_LinphoneCallLogImpl_getStatus(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return (jlong)((LinphoneCallLog*)ptr)->status; +} extern "C" jlong Java_org_linphone_core_LinphoneCallLogImpl_getTo(JNIEnv* env ,jobject thiz ,jlong ptr) { From 23d589cec01361b7c08528cd7433d5b01c0579bb Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 12 Jun 2012 17:21:11 +0200 Subject: [PATCH 12/19] fix bugs in call status, write codecs config immediately --- coreapi/callbacks.c | 15 ++++++++-- coreapi/linphonecall.c | 10 +++++-- coreapi/linphonecore.c | 67 ++++++++++++++++++++++++------------------ coreapi/linphonecore.h | 3 +- coreapi/misc.c | 1 + coreapi/private.h | 1 + gtk/calllogs.c | 21 ++++++++++++- 7 files changed, 83 insertions(+), 35 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index d7bc861ba..8ec8f39b1 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -484,9 +484,18 @@ static void call_terminated(SalOp *op, const char *from){ if (call==NULL) return; - if (linphone_call_get_state(call)==LinphoneCallEnd || linphone_call_get_state(call)==LinphoneCallError){ - ms_warning("call_terminated: ignoring."); - return; + switch(linphone_call_get_state(call)){ + case LinphoneCallEnd: + case LinphoneCallError: + ms_warning("call_terminated: ignoring."); + return; + break; + case LinphoneCallIncomingReceived: + case LinphoneCallIncomingEarlyMedia: + call->reason=LinphoneReasonNotAnswered; + break; + default: + break; } ms_message("Current call terminated..."); //we stop the call only if we have this current call or if we are in call diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index f010a7e79..ac8460291 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -497,8 +497,14 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const call->state=cstate; } if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){ - if (call->reason==LinphoneReasonDeclined){ - call->log->status=LinphoneCallDeclined; + switch(call->reason){ + case LinphoneReasonDeclined: + call->log->status=LinphoneCallDeclined; + case LinphoneReasonNotAnswered: + call->log->status=LinphoneCallMissed; + break; + default: + break; } linphone_call_set_terminated (call); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c0531ae9a..3bc23b344 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1319,6 +1319,7 @@ int linphone_core_set_audio_codecs(LinphoneCore *lc, MSList *codecs) { if (lc->codecs_conf.audio_codecs!=NULL) ms_list_free(lc->codecs_conf.audio_codecs); lc->codecs_conf.audio_codecs=codecs; + _linphone_core_codec_config_write(lc); return 0; } @@ -1333,6 +1334,7 @@ int linphone_core_set_video_codecs(LinphoneCore *lc, MSList *codecs) { if (lc->codecs_conf.video_codecs!=NULL) ms_list_free(lc->codecs_conf.video_codecs); lc->codecs_conf.video_codecs=codecs; + _linphone_core_codec_config_write(lc); return 0; } @@ -1827,6 +1829,7 @@ void linphone_core_iterate(LinphoneCore *lc){ ms_message("incoming call ringing for %i seconds",elapsed); if (elapsed>lc->sip_conf.inc_timeout){ call->log->status=LinphoneCallMissed; + call->reason=LinphoneReasonNotAnswered; linphone_core_terminate_call(lc,call); } } @@ -2569,7 +2572,8 @@ int linphone_core_abort_call(LinphoneCore *lc, LinphoneCall *call, const char *e static void terminate_call(LinphoneCore *lc, LinphoneCall *call){ if (call->state==LinphoneCallIncomingReceived){ - call->reason=LinphoneReasonDeclined; + if (call->reason!=LinphoneReasonNotAnswered) + call->reason=LinphoneReasonDeclined; } /*stop ringing*/ if (lc->ringstream!=NULL) { @@ -4261,38 +4265,43 @@ void video_config_uninit(LinphoneCore *lc) ms_free(lc->video_conf.cams); } -void codecs_config_uninit(LinphoneCore *lc) -{ - PayloadType *pt; - codecs_config_t *config=&lc->codecs_conf; - MSList *node; - char key[50]; - int index; - index=0; - for(node=config->audio_codecs;node!=NULL;node=ms_list_next(node)){ - pt=(PayloadType*)(node->data); +void _linphone_core_codec_config_write(LinphoneCore *lc){ + if (linphone_core_ready(lc)){ + PayloadType *pt; + codecs_config_t *config=&lc->codecs_conf; + MSList *node; + char key[50]; + int index; + index=0; + for(node=config->audio_codecs;node!=NULL;node=ms_list_next(node)){ + pt=(PayloadType*)(node->data); + sprintf(key,"audio_codec_%i",index); + lp_config_set_string(lc->config,key,"mime",pt->mime_type); + lp_config_set_int(lc->config,key,"rate",pt->clock_rate); + lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); + index++; + } sprintf(key,"audio_codec_%i",index); - lp_config_set_string(lc->config,key,"mime",pt->mime_type); - lp_config_set_int(lc->config,key,"rate",pt->clock_rate); - lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); - index++; - } - sprintf(key,"audio_codec_%i",index); - lp_config_clean_section (lc->config,key); + lp_config_clean_section (lc->config,key); - index=0; - for(node=config->video_codecs;node!=NULL;node=ms_list_next(node)){ - pt=(PayloadType*)(node->data); + index=0; + for(node=config->video_codecs;node!=NULL;node=ms_list_next(node)){ + pt=(PayloadType*)(node->data); + sprintf(key,"video_codec_%i",index); + lp_config_set_string(lc->config,key,"mime",pt->mime_type); + lp_config_set_int(lc->config,key,"rate",pt->clock_rate); + lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); + lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp); + index++; + } sprintf(key,"video_codec_%i",index); - lp_config_set_string(lc->config,key,"mime",pt->mime_type); - lp_config_set_int(lc->config,key,"rate",pt->clock_rate); - lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt)); - lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp); - index++; + lp_config_clean_section (lc->config,key); } - sprintf(key,"video_codec_%i",index); - lp_config_clean_section (lc->config,key); +} +static void codecs_config_uninit(LinphoneCore *lc) +{ + _linphone_core_codec_config_write(lc); ms_list_free(lc->codecs_conf.audio_codecs); ms_list_free(lc->codecs_conf.video_codecs); } @@ -4584,6 +4593,8 @@ const char *linphone_reason_to_string(LinphoneReason err){ return "Call declined"; case LinphoneReasonNotFound: return "User not found"; + case LinphoneReasonNotAnswered: + return "Not answered"; } return "unknown error"; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 59dbca0cb..ae3f9cb15 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -205,7 +205,8 @@ enum _LinphoneReason{ LinphoneReasonNoResponse, /**codecs_conf.audio_codecs,pt) || ms_list_find(lc->codecs_conf.video_codecs,pt)){ payload_type_set_enable(pt,enabled); + _linphone_core_codec_config_write(lc); return 0; } ms_error("Enabling codec not in audio or video list of PayloadType !"); diff --git a/coreapi/private.h b/coreapi/private.h index 773e77882..1ab7a6a7d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -568,6 +568,7 @@ bool_t linphone_core_sound_resources_available(LinphoneCore *lc); void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, LinphoneCall *newcall); void __linphone_core_invalidate_registers(LinphoneCore* lc); +void _linphone_core_codec_config_write(LinphoneCore *lc); #define HOLD_OFF (0) #define HOLD_ON (1) diff --git a/gtk/calllogs.c b/gtk/calllogs.c index 5ff2a08eb..bd5969ec8 100644 --- a/gtk/calllogs.c +++ b/gtk/calllogs.c @@ -57,6 +57,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){ const char *display; gchar *logtxt, *minutes, *seconds; gchar quality[20]; + const char *status=NULL; display=linphone_address_get_display_name (la); if (display==NULL){ @@ -67,17 +68,35 @@ void linphone_gtk_call_log_update(GtkWidget *w){ if (cl->quality!=-1){ snprintf(quality,sizeof(quality),"%.1f",cl->quality); } + switch(cl->status){ + case LinphoneCallAborted: + status=_("Aborted"); + break; + case LinphoneCallMissed: + status=_("Missed"); + break; + case LinphoneCallDeclined: + status=_("Declined"); + break; + default: + break; + } minutes=g_markup_printf_escaped( ngettext("%i minute", "%i minutes", cl->duration/60), cl->duration/60); seconds=g_markup_printf_escaped( ngettext("%i second", "%i seconds", cl->duration%60), cl->duration%60); - logtxt=g_markup_printf_escaped( + if (status==NULL) logtxt=g_markup_printf_escaped( _("%s\t%s\t" "Quality: %s\n%s\t%s %s\t"), display, addr, cl->quality!=-1 ? quality : _("n/a"), cl->start_date, minutes, seconds); + else logtxt=g_markup_printf_escaped( + _("%s\t%s\t" + "\n%s\t%s"), + display, addr, + cl->start_date, status); g_free(minutes); g_free(seconds); gtk_list_store_append (store,&iter); From 160dc76b0efccc8ef78f006718dd6029f54b10fe Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 10:15:16 +0200 Subject: [PATCH 13/19] Created and exported some methods to manage call logs from Java --- coreapi/linphonecore.c | 8 ++++++++ coreapi/linphonecore.h | 2 ++ coreapi/linphonecore_jni.cc | 12 ++++++++++++ java/common/org/linphone/core/LinphoneCallLog.java | 2 ++ java/common/org/linphone/core/LinphoneCore.java | 11 +++++++++++ 5 files changed, 35 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c0531ae9a..ada24237d 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3485,6 +3485,14 @@ void linphone_core_clear_call_logs(LinphoneCore *lc){ call_logs_write_to_config_file(lc); } +int linphone_core_get_missed_calls_count(LinphoneCore *lc) { + return lc->missed_calls; +} + +void linphone_core_remove_call_log(LinphoneCore *lc, void *data) { + lc->call_logs = ms_list_remove(lc->call_logs, data); +} + static void toggle_video_preview(LinphoneCore *lc, bool_t val){ #ifdef VIDEO_ENABLED if (val){ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 59dbca0cb..a59353a21 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -969,6 +969,8 @@ void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val); /* returns a list of LinphoneCallLog */ const MSList * linphone_core_get_call_logs(LinphoneCore *lc); void linphone_core_clear_call_logs(LinphoneCore *lc); +int linphone_core_get_missed_calls_count(LinphoneCore *lc); +void linphone_core_remove_call_log(LinphoneCore *lc, void *data); /* video support */ bool_t linphone_core_video_supported(LinphoneCore *lc); diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 52f5d24ad..f3ba28685 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -642,6 +642,18 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_stopDtmf( JNIEnv* env linphone_core_stop_dtmf((LinphoneCore*)lc); } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_getMissedCallsCount(JNIEnv* env + ,jobject thiz + ,jlong lc) { + linphone_core_get_missed_calls_count((LinphoneCore*)lc); +} + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeCallLog(JNIEnv* env + ,jobject thiz + ,jlong lc, jlong log) { + linphone_core_remove_call_log((LinphoneCore*)lc, (void*) log); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_clearCallLogs(JNIEnv* env ,jobject thiz ,jlong lc) { diff --git a/java/common/org/linphone/core/LinphoneCallLog.java b/java/common/org/linphone/core/LinphoneCallLog.java index 015f071df..c56f324d1 100644 --- a/java/common/org/linphone/core/LinphoneCallLog.java +++ b/java/common/org/linphone/core/LinphoneCallLog.java @@ -94,4 +94,6 @@ public interface LinphoneCallLog { * @return */ public CallStatus getStatus(); + + public long getNativePtr(); } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 0d8e14ae9..b6830863c 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -20,6 +20,7 @@ package org.linphone.core; import java.util.Vector; +import org.linphone.core.LinphoneCallLog; import org.linphone.core.LinphoneCallParams; /** @@ -759,4 +760,14 @@ public interface LinphoneCore { void setUserAgent(String name, String version); void setCpuCount(int count); + + /** + * remove a call log + */ + public void removeCallLog(LinphoneCallLog log); + + /** + * @return count of missed calls + */ + public int getMissedCallsCount(); } From d72e9c553ebc58de52ada8987f9d08e61c87d129 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 10:34:52 +0200 Subject: [PATCH 14/19] Save the logs removed --- coreapi/linphonecore.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 9caa52dc3..134d38d34 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3495,6 +3495,7 @@ int linphone_core_get_missed_calls_count(LinphoneCore *lc) { void linphone_core_remove_call_log(LinphoneCore *lc, void *data) { lc->call_logs = ms_list_remove(lc->call_logs, data); + call_logs_write_to_config_file(lc); } static void toggle_video_preview(LinphoneCore *lc, bool_t val){ From 9ee07aa8ffbcaf12159946b3b91bfb77d4cf13bb Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 14:06:52 +0200 Subject: [PATCH 15/19] Added JNI method to get call start date in log --- coreapi/linphonecore_jni.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index f3ba28685..35ee7f26d 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1146,6 +1146,12 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallLogImpl_isIncoming(JNIEnv ,jlong ptr) { return ((LinphoneCallLog*)ptr)->dir==LinphoneCallIncoming?JNI_TRUE:JNI_FALSE; } +extern "C" jstring Java_org_linphone_core_LinphoneCallLogImpl_getStartDate(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + jstring jvalue =env->NewStringUTF(((LinphoneCallLog*)ptr)->start_date); + return jvalue; +} /*payloadType*/ extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) { From f1f3c3c5e75931947fb4d8e265ef7f5e1fda6616 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 14:11:14 +0200 Subject: [PATCH 16/19] Added LinphoneCallLog interface previously exported JNI method --- java/common/org/linphone/core/LinphoneCallLog.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/java/common/org/linphone/core/LinphoneCallLog.java b/java/common/org/linphone/core/LinphoneCallLog.java index c56f324d1..fa1bc2ae5 100644 --- a/java/common/org/linphone/core/LinphoneCallLog.java +++ b/java/common/org/linphone/core/LinphoneCallLog.java @@ -96,4 +96,9 @@ public interface LinphoneCallLog { public CallStatus getStatus(); public long getNativePtr(); + + /** + * @return a human readble String with the start date/time of the call + */ + public String getStartDate(); } From cc211d4813f09a75f9fe27484e55031d39c2aee2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 14:15:48 +0200 Subject: [PATCH 17/19] Exported JNI method to get call duration from log --- coreapi/linphonecore_jni.cc | 5 +++++ java/common/org/linphone/core/LinphoneCallLog.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 35ee7f26d..d45f6009b 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1152,6 +1152,11 @@ extern "C" jstring Java_org_linphone_core_LinphoneCallLogImpl_getStartDate(JNIEn jstring jvalue =env->NewStringUTF(((LinphoneCallLog*)ptr)->start_date); return jvalue; } +extern "C" jint Java_org_linphone_core_LinphoneCallLogImpl_getCallDuration(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + return ((LinphoneCallLog*)ptr)->duration; +} /*payloadType*/ extern "C" jstring Java_org_linphone_core_PayloadTypeImpl_toString(JNIEnv* env,jobject thiz,jlong ptr) { diff --git a/java/common/org/linphone/core/LinphoneCallLog.java b/java/common/org/linphone/core/LinphoneCallLog.java index fa1bc2ae5..98bf40c50 100644 --- a/java/common/org/linphone/core/LinphoneCallLog.java +++ b/java/common/org/linphone/core/LinphoneCallLog.java @@ -101,4 +101,9 @@ public interface LinphoneCallLog { * @return a human readble String with the start date/time of the call */ public String getStartDate(); + + /** + * @return the call duration, in seconds + */ + public int getCallDuration(); } From 0d922d4c801cf6c9179638e5311485e871889284 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jun 2012 15:11:25 +0200 Subject: [PATCH 18/19] Added resetMissedCallsCount to linphone core and exported via JNI --- coreapi/linphonecore.c | 4 ++++ coreapi/linphonecore.h | 1 + coreapi/linphonecore_jni.cc | 6 ++++++ java/common/org/linphone/core/LinphoneCore.java | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 134d38d34..41b9e2dda 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3493,6 +3493,10 @@ int linphone_core_get_missed_calls_count(LinphoneCore *lc) { return lc->missed_calls; } +void linphone_core_reset_missed_calls_count(LinphoneCore *lc) { + lc->missed_calls=0; +} + void linphone_core_remove_call_log(LinphoneCore *lc, void *data) { lc->call_logs = ms_list_remove(lc->call_logs, data); call_logs_write_to_config_file(lc); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 531950d72..c9c6fc1a1 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -971,6 +971,7 @@ void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val); const MSList * linphone_core_get_call_logs(LinphoneCore *lc); void linphone_core_clear_call_logs(LinphoneCore *lc); int linphone_core_get_missed_calls_count(LinphoneCore *lc); +void linphone_core_reset_missed_calls_count(LinphoneCore *lc); void linphone_core_remove_call_log(LinphoneCore *lc, void *data); /* video support */ diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index d45f6009b..4393e3a3b 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -648,6 +648,12 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_getMissedCallsCount(JNIE linphone_core_get_missed_calls_count((LinphoneCore*)lc); } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_resetMissedCallsCount(JNIEnv* env + ,jobject thiz + ,jlong lc) { + linphone_core_reset_missed_calls_count((LinphoneCore*)lc); +} + extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeCallLog(JNIEnv* env ,jobject thiz ,jlong lc, jlong log) { diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index b6830863c..86559f43f 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -770,4 +770,9 @@ public interface LinphoneCore { * @return count of missed calls */ public int getMissedCallsCount(); + + /** + * Set missed calls count to zero + */ + public void resetMissedCallsCount(); } From 89296804e4adc3bddf8248187ff328ebf2d74438 Mon Sep 17 00:00:00 2001 From: Yann Diorcet Date: Wed, 13 Jun 2012 17:38:13 +0200 Subject: [PATCH 19/19] Update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 343d9116b..5b865fce6 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 343d9116b35e2f80c01e77a4bc7bbf898126cd53 +Subproject commit 5b865fce6a98d20b9b8696784b5e7e6467f2ced0