From 82eaf99776603b4f6e8eff8d1836f9184083255e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 17 Nov 2013 22:29:59 +0100 Subject: [PATCH 01/38] adapt to new resolver api. --- coreapi/bellesip_sal/sal_impl.c | 10 ++++++---- coreapi/misc.c | 6 +++--- coreapi/private.h | 2 +- include/sal/sal.h | 6 ++++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index b3a7cfc78..f1daaa1bd 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -839,13 +839,15 @@ void sal_enable_test_features(Sal*ctx, bool_t enabled){ ctx->enable_test_features=enabled; } -unsigned long sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data){ - return belle_sip_stack_resolve_a(sal->stack,name,port,family,(belle_sip_resolver_callback_t)cb,data); +SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data){ + return (SalResolverContext*)belle_sip_stack_resolve_a(sal->stack,name,port,family,(belle_sip_resolver_callback_t)cb,data); } -void sal_resolve_cancel(Sal *sal, unsigned long id){ - belle_sip_stack_resolve_cancel(sal->stack,id); +/* +void sal_resolve_cancel(Sal *sal, SalResolverContext* ctx){ + belle_sip_stack_resolve_cancel(sal->stack,ctx); } +*/ void sal_enable_unconditional_answer(Sal *sal,int value) { belle_sip_provider_enable_unconditional_answer(sal->prov,value); diff --git a/coreapi/misc.c b/coreapi/misc.c index 7d9b70b3f..c96fde835 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -633,7 +633,7 @@ static void stun_server_resolved(LinphoneCore *lc, const char *name, struct addr ms_warning("Stun server resolution failed."); } lc->net_conf.stun_addrinfo=addrinfo; - lc->net_conf.stun_res_id=0; + lc->net_conf.stun_res=NULL; } void linphone_core_resolve_stun_server(LinphoneCore *lc){ @@ -642,7 +642,7 @@ void linphone_core_resolve_stun_server(LinphoneCore *lc){ char host[NI_MAXHOST]; int port=3478; linphone_parse_host_port(server,host,sizeof(host),&port); - lc->net_conf.stun_res_id=sal_resolve_a(lc->sal,host,port,AF_UNSPEC,(SalResolverCallback)stun_server_resolved,lc); + lc->net_conf.stun_res=sal_resolve_a(lc->sal,host,port,AF_UNSPEC,(SalResolverCallback)stun_server_resolved,lc); } } @@ -663,7 +663,7 @@ const struct addrinfo *linphone_core_get_stun_server_addrinfo(LinphoneCore *lc){ int wait_ms=0; int wait_limit=1000; linphone_core_resolve_stun_server(lc); - while (!lc->net_conf.stun_addrinfo && lc->net_conf.stun_res_id!=0 && wait_msnet_conf.stun_addrinfo && lc->net_conf.stun_res!=NULL && wait_mssal); ms_usleep(50000); wait_ms+=50; diff --git a/coreapi/private.h b/coreapi/private.h index 20397cefc..69eead0f1 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -498,7 +498,7 @@ typedef struct net_config char *nat_address_ip; /* ip translated from nat_address */ char *stun_server; struct addrinfo *stun_addrinfo; - unsigned long stun_res_id; + SalResolverContext * stun_res; int download_bw; int upload_bw; int mtu; diff --git a/include/sal/sal.h b/include/sal/sal.h index dd6a8f5db..ad230c9ae 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -594,8 +594,10 @@ void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t ipl typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list); -unsigned long sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data); -void sal_resolve_cancel(Sal *sal, unsigned long id); +typedef struct SalResolverContext SalResolverContext; + +SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data); +//void sal_resolve_cancel(Sal *sal, SalResolverContext *ctx); SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name, const char *value); const char *sal_custom_header_find(const SalCustomHeader *ch, const char *name); From d5a091ba0a904fcd0de7fe89b5c2ebaefa8ff0b2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 18 Nov 2013 11:33:47 +0100 Subject: [PATCH 02/38] Updated README + fix SIP_INFO DTMF crash when trying to send a DTMF while call is ringing --- README | 3 ++- coreapi/bellesip_sal/sal_op_call.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README b/README index 0efd14949..8913f1205 100644 --- a/README +++ b/README @@ -10,6 +10,7 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol. - you need at least: - belle-sip>=1.0.0 - speex>=1.2.0 (including libspeexdsp part) + - libxml2 + if you want the gtk/glade interface: - libgtk >=2.16.0 @@ -32,7 +33,7 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol. Here is the command line to get these dependencies installed for Ubuntu && Debian - $ sudo apt-get install libtool intltool libgtk2.0-dev libosip2-dev libexosip2-dev libspeexdsp-dev libavcodec-dev libswscale-dev libx11-dev libvx-dev libgl1-mesa-dev libglew1.6-dev libv4l-dev + $ sudo apt-get install libtool intltool libgtk2.0-dev libosip2-dev libexosip2-dev libspeexdsp-dev libavcodec-dev libswscale-dev libx11-dev libxv-dev libgl1-mesa-dev libglew1.6-dev libv4l-dev libxml2-dev + for optional library $ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev libsoup2.4-dev libsqlite3-dev libupnp4-dev diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 8a7037491..08059fb22 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -693,7 +693,7 @@ SalMediaDescription * sal_call_get_final_media_description(SalOp *h){ } int sal_call_send_dtmf(SalOp *h, char dtmf){ - if (h->dialog){ + if (h->dialog && (belle_sip_dialog_get_state(h->dialog) == BELLE_SIP_DIALOG_CONFIRMED || belle_sip_dialog_get_state(h->dialog) == BELLE_SIP_DIALOG_EARLY)){ belle_sip_request_t *req=belle_sip_dialog_create_queued_request(h->dialog,"INFO"); if (req){ int bodylen; From c75c44d56bcaa5532b492ff690395ba417e7fd18 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 18 Nov 2013 11:35:14 +0100 Subject: [PATCH 03/38] update README for mac --- README.macos | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.macos b/README.macos index 87817ac54..1713b7968 100644 --- a/README.macos +++ b/README.macos @@ -7,9 +7,11 @@ You need: - Macports: http://www.macports.org/ Download and install macports using its user friendly installer. -- In order to enable generation of bundle for multiple macos version it is recommended to edit /opt/local/etc/macports/macports.conf to add the - following line: - macosx_deployment_target 10.6 +- In order to enable generation of bundle for multiple macos version and 32 bit processors, it is recommended to: + 1) edit /opt/local/etc/macports/macports.conf to add the following line: + macosx_deployment_target 10.6 + 2) edit /opt/local/etc/macports/variants.conf to add the following line: + +universal - Install build time dependencies $ sudo port install automake autoconf libtool intltool @@ -34,7 +36,16 @@ You need: The softwares below need to be compiled manually. To ensure compatibility with multiple mac os version it is recommended to do: $ export MACOSX_DEPLOYMENT_TARGET=10.6 + $ export CFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" + $ export OBJCFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" + $ export CXXFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" + $ export LDFLAGS="-arch i386 -arch x86_64 -mmacosx-version-min=10.5" +- Install polarssl (encryption library used by belle-sip) + $ git clone git://git.linphone.org/polarssl.git -b linphone + $ cd polarssl + $ ./autogen.sh && ./configure --prefix=/opt/local && make + $ sudo make install - Install belle-sip (sip stack) $ git clone git://git.linphone.org/belle-sip.git From 5ad51122ba07d8600ba601cfb92f0e03e1862c88 Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Mon, 18 Nov 2013 16:28:32 +0100 Subject: [PATCH 04/38] Fix compilation for Macos 32bit --- tools/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/Makefile.am b/tools/Makefile.am index 6fa7fadb4..5ef2535ad 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -12,7 +12,7 @@ COMMON_CFLAGS=\ $(LIBXML2_CFLAGS) #-fpermissive to workaround a g++ bug on macos 32bit SDK. -AM_CXXFLAGS=$(LIBXML2_CFLAGS) $(STRICT_OPTIONS) -fpermissive +AM_CXXFLAGS=$(LIBXML2_CFLAGS) -fpermissive $(STRICT_OPTIONS) EXTRA_DIST=xml2lpc_jni.cc lpc2xml_jni.cc From 2f415bc619c758155b77aef31f0d3392717c7496 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 18 Nov 2013 22:23:41 +0100 Subject: [PATCH 05/38] modify JNI to allow passing raw data in LinphoneContent. --- coreapi/linphonecore_jni.cc | 67 ++++++++++++------- .../org/linphone/core/LinphoneContent.java | 16 +++++ .../linphone/core/LinphoneCoreFactory.java | 7 +- .../linphone/core/LinphoneContentImpl.java | 31 +++++++-- .../core/LinphoneCoreFactoryImpl.java | 8 ++- .../org/linphone/core/LinphoneCoreImpl.java | 10 +-- .../org/linphone/core/LinphoneEventImpl.java | 12 ++-- 7 files changed, 110 insertions(+), 41 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a0e212c26..fa583f144 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3102,7 +3102,7 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getUpnpExternalIpaddr * Signature: (JJLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIEnv *env, jobject jcore, jlong coreptr, jlong addrptr, - jstring jevname, jint expires, jstring jtype, jstring jsubtype, jstring jdata){ + jstring jevname, jint expires, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneCore *lc=(LinphoneCore*)coreptr; LinphoneAddress *addr=(LinphoneAddress*)addrptr; LinphoneContent content={0}; @@ -3114,14 +3114,16 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } ev=linphone_core_subscribe(lc,addr,evname,expires,content.type ? &content : NULL); if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } env->ReleaseStringUTFChars(jevname,evname); if (ev){ @@ -3136,7 +3138,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_subscribe(JNIE * Signature: (JJLjava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; */ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv *env, jobject jobj, jlong coreptr, jlong addrptr, jstring jevname, jint expires, - jstring jtype, jstring jsubtype, jstring jdata){ + jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneCore *lc=(LinphoneCore*)coreptr; LinphoneAddress *addr=(LinphoneAddress*)addrptr; LinphoneContent content={0}; @@ -3148,14 +3150,16 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCoreImpl_publish(JNIEnv if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } ev=linphone_core_publish(lc,addr,evname,expires,content.type ? &content : NULL); if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } env->ReleaseStringUTFChars(jevname,evname); if (ev){ @@ -3295,15 +3299,22 @@ extern "C" jintArray Java_org_linphone_core_LpConfigImpl_getIntRange(JNIEnv *env static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content){ jclass contentClass; jmethodID ctor; - jstring jtype, jsubtype, jdata; + jstring jtype, jsubtype, jencoding; + jbyteArray jdata=NULL; contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl")); - ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); + ctor = env->GetMethodID(contentClass,"", "(Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;)V"); jtype=env->NewStringUTF(content->type); jsubtype=env->NewStringUTF(content->subtype); - jdata=content->data ? env->NewStringUTF((const char*)content->data) : NULL; - jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata); + jencoding=content->encoding ? env->NewStringUTF(content->encoding) : NULL; + + if (content->data){ + jdata=env->NewByteArray(content->size); + env->SetByteArrayRegion(jdata,0,content->size,(jbyte*)content->data); + } + + jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata,jencoding); env->DeleteGlobalRef(contentClass); return jobj; } @@ -3327,7 +3338,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_getCont * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneInfoMessageImpl_setContent(JNIEnv *env, jobject jobj, jlong infoptr, jstring jtype, jstring jsubtype, jstring jdata){ - LinphoneContent content; + LinphoneContent content={0}; content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); @@ -3428,7 +3439,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_denySubscription * Method: notify * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3436,8 +3447,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_notify(ev,content.type ? &content : NULL); @@ -3445,7 +3457,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } @@ -3455,7 +3468,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_notify(JNIEnv *e * Method: updateSubscribe * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3463,8 +3476,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_update_subscribe(ev,content.type ? &content : NULL); @@ -3472,7 +3486,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } @@ -3482,7 +3497,7 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updateSubscribe( * Method: updatePublish * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I */ -JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jstring jdata){ +JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JNIEnv *env, jobject jobj, jlong evptr, jstring jtype, jstring jsubtype, jbyteArray jdata, jstring jencoding){ LinphoneContent content={0}; LinphoneEvent *ev=(LinphoneEvent*)evptr; jint err; @@ -3490,8 +3505,9 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN if (jtype){ content.type=(char*)env->GetStringUTFChars(jtype,NULL); content.subtype=(char*)env->GetStringUTFChars(jsubtype,NULL); - content.data=(void*)env->GetStringUTFChars(jdata,NULL); - content.size=strlen((char*)content.data); + content.encoding=jencoding ? (char*)env->GetStringUTFChars(jsubtype,NULL) : NULL; + content.data=(void*)env->GetByteArrayElements(jdata,NULL); + content.size=env->GetArrayLength(jdata); } err=linphone_event_update_publish(ev,content.type ? &content : NULL); @@ -3499,7 +3515,8 @@ JNIEXPORT jint JNICALL Java_org_linphone_core_LinphoneEventImpl_updatePublish(JN if (jtype){ env->ReleaseStringUTFChars(jtype,content.type); env->ReleaseStringUTFChars(jsubtype,content.subtype); - env->ReleaseStringUTFChars(jdata,(char*)content.data); + if (jencoding) env->ReleaseStringUTFChars(jencoding,content.encoding); + env->ReleaseByteArrayElements(jdata,(jbyte*)content.data,JNI_ABORT); } return err; } diff --git a/java/common/org/linphone/core/LinphoneContent.java b/java/common/org/linphone/core/LinphoneContent.java index b3811006f..10c6e3dc9 100644 --- a/java/common/org/linphone/core/LinphoneContent.java +++ b/java/common/org/linphone/core/LinphoneContent.java @@ -17,11 +17,19 @@ public interface LinphoneContent { * @return the subtype */ String getSubtype(); + /** + * Get the encoding applied to the data, can be null if no encoding. + **/ + String getEncoding(); /** * Get the data as a string. * @return the data */ String getDataAsString(); + /** + * Get the data as a byte array. + **/ + byte [] getData(); /** * Get the data size. * @return the data size. @@ -38,9 +46,17 @@ public interface LinphoneContent { * @param subtype the subtype */ void setSubtype(String subtype); + /** + * Set the encoding applied to the data, can be null if no encoding. + **/ + void setEncoding(String encoding); /** * Set the data, supplied as String. * @param data the data */ void setStringData(String data); + /** + * Set the data, as a byte buffer. + **/ + void setData(byte data[]); } diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index dfbeb883b..95cfdeaf0 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -108,10 +108,15 @@ abstract public class LinphoneCoreFactory { abstract public LinphoneFriend createLinphoneFriend(); /** - * Create a LinphoneContent object + * Create a LinphoneContent object from string data. */ abstract public LinphoneContent createLinphoneContent(String type, String subType, String data); + /** + * Create a LinphoneContent object from byte array. + */ + abstract public LinphoneContent createLinphoneContent(String type, String subType,byte [] data, String encoding); + /** * Create a PresenceActivity object. */ diff --git a/java/impl/org/linphone/core/LinphoneContentImpl.java b/java/impl/org/linphone/core/LinphoneContentImpl.java index f74711042..b12e6580f 100644 --- a/java/impl/org/linphone/core/LinphoneContentImpl.java +++ b/java/impl/org/linphone/core/LinphoneContentImpl.java @@ -1,11 +1,14 @@ package org.linphone.core; public class LinphoneContentImpl implements LinphoneContent { - private String mType, mSubtype, mData; - public LinphoneContentImpl(String type, String subtype, String data){ + private String mType, mSubtype, mEncoding; + private byte[] mData; + + public LinphoneContentImpl(String type, String subtype, byte data[], String encoding ){ mType=type; mSubtype=subtype; mData=data; + mEncoding=encoding; } @Override @@ -20,12 +23,12 @@ public class LinphoneContentImpl implements LinphoneContent { @Override public String getDataAsString() { - return mData; + return new String(mData); } @Override public int getSize() { - return mData.length(); + return mData.length; } @Override @@ -40,7 +43,27 @@ public class LinphoneContentImpl implements LinphoneContent { @Override public void setStringData(String data) { + mData=data.getBytes(); + } + + @Override + public void setData(byte data[]){ mData=data; } + @Override + public String getEncoding() { + return mEncoding; + } + + @Override + public byte[] getData() { + return mData; + } + + @Override + public void setEncoding(String encoding) { + mEncoding=encoding; + } + } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index d2f635d4d..e526b47b5 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -151,10 +151,16 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { return new LinphoneAuthInfoImpl(username, userid, passwd, ha1, realm, domain); } + @Override + public LinphoneContent createLinphoneContent(String type, String subType, + byte [] data, String encoding) { + return new LinphoneContentImpl(type,subType,data,encoding); + } + @Override public LinphoneContent createLinphoneContent(String type, String subType, String data) { - return new LinphoneContentImpl(type,subType,data); + return new LinphoneContentImpl(type,subType,data.getBytes(),null); } @Override diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index f5740ff41..420547e57 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -1028,19 +1028,21 @@ class LinphoneCoreImpl implements LinphoneCore { return new LinphoneInfoMessageImpl(createInfoMessage(nativePtr)); } - private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, String data); + private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding); @Override public LinphoneEvent subscribe(LinphoneAddress resource, String eventname, int expires, LinphoneContent content) { return (LinphoneEvent)subscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires, - content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getDataAsString() : null); + content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null, + content!=null ? content.getEncoding() : null); } - private native Object publish(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, String data); + private native Object publish(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding); @Override public LinphoneEvent publish(LinphoneAddress resource, String eventname, int expires, LinphoneContent content) { return (LinphoneEvent)publish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires, - content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getDataAsString() : null); + content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null, + content!=null ? content.getEncoding() : null); } public void setChatDatabasePath(String path) { diff --git a/java/impl/org/linphone/core/LinphoneEventImpl.java b/java/impl/org/linphone/core/LinphoneEventImpl.java index ab201af99..9890f7cdf 100644 --- a/java/impl/org/linphone/core/LinphoneEventImpl.java +++ b/java/impl/org/linphone/core/LinphoneEventImpl.java @@ -26,22 +26,22 @@ public class LinphoneEventImpl implements LinphoneEvent { denySubscription(mNativePtr,reason.mValue); } - private native int notify(long nativeptr, String type, String subtype, String data); + private native int notify(long nativeptr, String type, String subtype, byte data[], String encoding); @Override public void notify(LinphoneContent content) { - notify(mNativePtr,content.getType(),content.getSubtype(),content.getDataAsString()); + notify(mNativePtr,content.getType(),content.getSubtype(),content.getData(),content.getEncoding()); } - private native int updateSubscribe(long nativePtr, String type, String subtype, String data); + private native int updateSubscribe(long nativePtr, String type, String subtype, byte data[], String encoding); @Override public void updateSubscribe(LinphoneContent content) { - updateSubscribe(mNativePtr,content.getType(), content.getSubtype(),content.getDataAsString()); + updateSubscribe(mNativePtr,content.getType(), content.getSubtype(),content.getData(),content.getEncoding()); } - private native int updatePublish(long nativePtr, String type, String subtype, String data); + private native int updatePublish(long nativePtr, String type, String subtype, byte data[], String encoding); @Override public void updatePublish(LinphoneContent content) { - updatePublish(mNativePtr,content.getType(), content.getSubtype(),content.getDataAsString()); + updatePublish(mNativePtr,content.getType(), content.getSubtype(),content.getData(),content.getEncoding()); } private native int terminate(long nativePtr); From df6e200585a62d95034032eef996fedf5a3f2015 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 19 Nov 2013 12:04:06 +0100 Subject: [PATCH 06/38] fix leaked streams in case of incoming call declined because media incompatible --- coreapi/linphonecall.c | 1 + coreapi/linphonecore.c | 1 + 2 files changed, 2 insertions(+) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7c24bbbd4..6786209cd 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -762,6 +762,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const static void linphone_call_destroy(LinphoneCall *obj) { ms_message("Call [%p] freed.",obj); + linphone_call_stop_media_streams(obj); #ifdef BUILD_UPNP linphone_call_delete_upnp_session(obj); #endif //BUILD_UPNP diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index df4be1090..fdf54e745 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2852,6 +2852,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ if (md){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ sal_call_decline(call->op,SalReasonMedia,NULL); + linphone_call_stop_media_streams(call); linphone_core_del_call(lc,call); linphone_call_unref(call); return; From d10666ae19560f86c413006c6504c7247735219e Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 19 Nov 2013 12:31:18 +0100 Subject: [PATCH 07/38] set record directory to home if no music dir --- gtk/main.c | 3 +++ mediastreamer2 | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/gtk/main.c b/gtk/main.c index 6aabf98c5..87c278ddd 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -797,6 +797,9 @@ gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_ date, id); } + if (!dir) { + ms_message ("No directory for music, using [%s] instead",dir=getenv("HOME")); + } return g_build_filename(dir,filename,NULL); } diff --git a/mediastreamer2 b/mediastreamer2 index a3c366b6b..3433e47bc 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit a3c366b6b5639f5c844ddbcd1d1f205ca7d8c22c +Subproject commit 3433e47bc8ed15b2800bbd448f6d22f79285e66d From 2b6dcf779aff72963fe1147990d21552ab1e96fe Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 19 Nov 2013 22:21:55 +0100 Subject: [PATCH 08/38] fix bugs in tests. --- tester/call_tester.c | 8 ++++++-- tester/message_tester.c | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index 267d2050e..8b984e498 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -382,12 +382,16 @@ static void call_failed_because_of_codecs(void) { static void call_with_dns_time_out(void) { LinphoneCoreManager* marie = linphone_core_manager_new2( "empty_rc", FALSE); LCSipTransports transport = {9773,0,0,0}; + int i; + linphone_core_set_sip_transports(marie->lc,&transport); linphone_core_iterate(marie->lc); sal_set_dns_timeout(marie->lc->sal,0); linphone_core_invite(marie->lc,"sip:toto@toto.com"); - linphone_core_iterate(marie->lc); - linphone_core_iterate(marie->lc); + for(i=0;i<10;i++){ + ms_usleep(200000); + linphone_core_iterate(marie->lc); + } CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingInit,1); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingProgress,1); CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); diff --git a/tester/message_tester.c b/tester/message_tester.c index 5b111a302..c3001c226 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -220,7 +220,7 @@ static void info_message_with_args(bool_t with_content) { info=linphone_core_create_info_message(marie->lc); linphone_info_message_add_header(info,"Weather","still bad"); if (with_content) { - LinphoneContent ct; + LinphoneContent ct={0}; ct.type="application"; ct.subtype="somexml"; ct.data=(void*)info_content; From 41e358f9768782c1ef4371e7e07749c2e0948669 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 19 Nov 2013 22:23:03 +0100 Subject: [PATCH 09/38] restore ms2 (previous commits rewinded it) --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 3433e47bc..785a5d8f7 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 3433e47bc8ed15b2800bbd448f6d22f79285e66d +Subproject commit 785a5d8f76c336a51f8a21997e9dcaee669d4ec4 From 4ecd0432cfadb89667c4c95b9606ed08f9108477 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 20 Nov 2013 09:39:07 +0100 Subject: [PATCH 10/38] fix no video build --- coreapi/linphonecore.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index fdf54e745..350dd3c40 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4897,8 +4897,10 @@ unsigned long linphone_core_get_native_video_window_id(const LinphoneCore *lc){ /* unsets the video id for all calls (indeed it may be kept by filters or videostream object itself by paused calls)*/ static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned long id){ +#ifdef VIDEO_ENABLED LinphoneCall *call; MSList *elem; +#endif if (id!=0 && id!=-1) { ms_error("Invalid use of unset_video_window_id()"); From c47812993d0b5c261acdc58823f5ede2c9d7fd34 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 20 Nov 2013 16:27:23 +0100 Subject: [PATCH 11/38] fix crash in ms2 --- coreapi/linphonecore.c | 8 ++++++-- mediastreamer2 | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index fdf54e745..1b5812b90 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -942,6 +942,7 @@ static void build_video_devices_table(LinphoneCore *lc){ static void video_config_read(LinphoneCore *lc){ #ifdef VIDEO_ENABLED int capture, display, self_view; + int automatic_video=1; #endif const char *str; #ifdef VIDEO_ENABLED @@ -958,11 +959,14 @@ static void video_config_read(LinphoneCore *lc){ lp_config_get_string(lc->config,"video","size","cif")); #ifdef VIDEO_ENABLED +#if defined(ANDROID) || defined(__ios) + automatic_video=0; +#endif capture=lp_config_get_int(lc->config,"video","capture",1); display=lp_config_get_int(lc->config,"video","display",1); self_view=lp_config_get_int(lc->config,"video","self_view",1); - vpol.automatically_initiate=lp_config_get_int(lc->config,"video","automatically_initiate",1); - vpol.automatically_accept=lp_config_get_int(lc->config,"video","automatically_accept",1); + vpol.automatically_initiate=lp_config_get_int(lc->config,"video","automatically_initiate",automatic_video); + vpol.automatically_accept=lp_config_get_int(lc->config,"video","automatically_accept",automatic_video); linphone_core_enable_video_capture(lc, capture); linphone_core_enable_video_display(lc, display); linphone_core_enable_video_preview(lc,lp_config_get_int(lc->config,"video","show_local",0)); diff --git a/mediastreamer2 b/mediastreamer2 index 785a5d8f7..c1be4195c 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 785a5d8f76c336a51f8a21997e9dcaee669d4ec4 +Subproject commit c1be4195ccc127199d3541a7a5e7ce0351fcde63 From e8225e64b94e845aec3d2b7907b705315fbee9b7 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 21 Nov 2013 13:52:51 +0100 Subject: [PATCH 12/38] Basic client certificates API --- coreapi/bellesip_sal/sal_impl.c | 50 +++++++++++++++++++++--- coreapi/callbacks.c | 68 +++++++++++++++++++++++++++++---- coreapi/sal.c | 2 + include/sal/sal.h | 49 ++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 13 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index f1daaa1bd..af7d077c7 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef HAVE_CONFIG_H #include "config.h" #endif + +typedef struct belle_sip_certificates_chain_t _SalCertificatesChain; +typedef struct belle_sip_signing_key_t _SalSigningKey; + /* rfc3323 4.2 Expressing Privacy Preferences @@ -367,14 +371,16 @@ static void process_transaction_terminated(void *user_ctx, const belle_sip_trans } -static void process_auth_requested(void *sal, belle_sip_auth_event_t *auth_event) { - SalAuthInfo* auth_info = sal_auth_info_create(auth_event); + +static void process_auth_requested(void *sal, belle_sip_auth_event_t *event) { + SalAuthInfo* auth_info = sal_auth_info_create(event); ((Sal*)sal)->callbacks.auth_requested(sal,auth_info); - belle_sip_auth_event_set_passwd(auth_event,(const char*)auth_info->password); - belle_sip_auth_event_set_ha1(auth_event,(const char*)auth_info->ha1); - belle_sip_auth_event_set_userid(auth_event,(const char*)auth_info->userid); + belle_sip_auth_event_set_passwd(event,(const char*)auth_info->password); + belle_sip_auth_event_set_ha1(event,(const char*)auth_info->ha1); + belle_sip_auth_event_set_userid(event,(const char*)auth_info->userid); + belle_sip_auth_event_set_signing_key(event,(belle_sip_signing_key_t *)auth_info->key); + belle_sip_auth_event_set_client_certificates_chain(event,(belle_sip_certificates_chain_t* )auth_info->certificates); sal_auth_info_delete(auth_info); - return; } Sal * sal_init(){ @@ -699,9 +705,21 @@ SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) { auth_info->realm = ms_strdup(belle_sip_auth_event_get_realm(event)); auth_info->username = ms_strdup(belle_sip_auth_event_get_username(event)); auth_info->domain = ms_strdup(belle_sip_auth_event_get_domain(event)); + auth_info->mode = belle_sip_auth_event_get_mode(event); return auth_info; } +SalAuthMode sal_auth_info_get_mode(const SalAuthInfo* auth_info) { return auth_info->mode; } +SalSigningKey *sal_auth_info_get_signing_key(const SalAuthInfo* auth_info) { return auth_info->key; } +SalCertificatesChain *sal_auth_info_get_certificates_chain(const SalAuthInfo* auth_info) { return auth_info->certificates; } +void sal_auth_info_set_mode(SalAuthInfo* auth_info, SalAuthMode mode) { auth_info->mode = mode; } +void sal_certificates_chain_delete(SalCertificatesChain *chain) { + belle_sip_object_unref((belle_sip_object_t *)chain); +} +void sal_signing_key_delete(SalSigningKey *key) { + belle_sip_object_unref((belle_sip_object_t *)key); +} + const char* sal_op_type_to_string(const SalOpType type) { switch(type) { case SalOpRegister: return "SalOpRegister"; @@ -852,3 +870,23 @@ void sal_resolve_cancel(Sal *sal, SalResolverContext* ctx){ void sal_enable_unconditional_answer(Sal *sal,int value) { belle_sip_provider_enable_unconditional_answer(sal->prov,value); } + +/** Parse a file containing either a certificate chain order in PEM format or a single DER cert + * @param auth_info structure where to store the result of parsing + * @param path path to certificate chain file + * @param format either PEM or DER + */ +void sal_certificates_chain_parse_file(SalAuthInfo* auth_info, const char* path, SalCertificateRawFormat format) { + auth_info->certificates = (SalCertificatesChain*) belle_sip_certificates_chain_parse_file(path, format); // + if (auth_info->certificates) belle_sip_object_ref((belle_sip_object_t *) auth_info->certificates); +} + +/** + * Parse a file containing either a private or public rsa key + * @param auth_info structure where to store the result of parsing + * @param passwd password (optionnal) + */ +void sal_signing_key_parse_file(SalAuthInfo* auth_info, const char* path, const char *passwd) { + auth_info->key = (SalSigningKey *) belle_sip_signing_key_parse_file(path, passwd); + if (auth_info->key) belle_sip_object_ref((belle_sip_object_t *) auth_info->key); +} diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 23f9663fa..ee125717f 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -25,6 +25,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mediastream.h" #include "lpconfig.h" +// stat +#ifndef WIN32 +#include +#include +#include +#endif + static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details); static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) { @@ -901,6 +908,46 @@ static void ping_reply(SalOp *op){ } } +static const char *get_client_cert_path(LinphoneCore *lc) { + static char cldir[200] = {0}; + #ifdef HAVE_GETENV + if (!cldir[0]) { + static char default_path[200] = {0}; + snprintf(default_path, sizeof(default_path), "%s%s", getenv("HOME"), "/linphone_certs"); + snprintf(cldir, sizeof(cldir), "%s", lp_config_get_string(lc->config,"sip","client_certificates_dir", default_path)); + } + #endif + return cldir; +} +static bool_t fill_auth_info_with_client_certificate(LinphoneCore *lc, SalAuthInfo* sai) { + char chain_file[200]; + char key_file[200]; + const char *path = get_client_cert_path(lc); + + snprintf(chain_file, sizeof(chain_file), "%s%s", path, "/chain.pem"); + + snprintf(key_file, sizeof(key_file), "%s%s", path, "/key.pem"); + +#ifndef WIN32 + { + // optinal check for files + struct stat st; + if (stat(key_file,&st)) { + ms_warning("No client certificate key found in %s", key_file); + return FALSE; + } + if (stat(chain_file,&st)) { + ms_warning("No client certificate chain found in %s", chain_file); + return FALSE; + } + } +#endif + + sal_certificates_chain_parse_file(sai, chain_file, SAL_CERTIFICATE_RAW_FORMAT_PEM ); + sal_signing_key_parse_file(sai, key_file, ""); + return sai->certificates && sai->key; +} + static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) { LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,sai->realm,sai->username,sai->domain); if (ai) { @@ -916,18 +963,25 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) { } static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) { LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); - if (fill_auth_info(lc,sai)) { - return TRUE; - } else { - if (lc->vtable.auth_info_requested) { - lc->vtable.auth_info_requested(lc,sai->realm,sai->username,sai->domain); - if (fill_auth_info(lc,sai)) { - return TRUE; + if (sai->mode == SalAuthModeHttpDigest) { + if (fill_auth_info(lc,sai)) { + return TRUE; + } else { + if (lc->vtable.auth_info_requested) { + lc->vtable.auth_info_requested(lc,sai->realm,sai->username,sai->domain); + if (fill_auth_info(lc,sai)) { + return TRUE; + } } + return FALSE; } + } else if (sai->mode == SalAuthModeTls) { + return fill_auth_info_with_client_certificate(lc,sai); + } else { return FALSE; } } + static void notify_refer(SalOp *op, SalReferStatus status){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*) sal_op_get_user_pointer(op); diff --git a/coreapi/sal.c b/coreapi/sal.c index 49e70b3c6..69ee5b6c2 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -483,6 +483,8 @@ void sal_auth_info_delete(SalAuthInfo* auth_info) { if (auth_info->realm) ms_free(auth_info->realm); if (auth_info->domain) ms_free(auth_info->domain); if (auth_info->password) ms_free(auth_info->password); + if (auth_info->certificates) sal_certificates_chain_delete(auth_info->certificates); + if (auth_info->key) sal_signing_key_delete(auth_info->key); ms_free(auth_info); } diff --git a/include/sal/sal.h b/include/sal/sal.h index ad230c9ae..86f20c60d 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -331,6 +331,29 @@ typedef enum SalTextDeliveryStatus{ SalTextDeliveryFailed }SalTextDeliveryStatus; +/** + * auth event mode + * */ +typedef enum SalAuthMode { + SalAuthModeHttpDigest, /** Digest authentication requested*/ + SalAuthModeTls /** Client certificate requested*/ +}SalAuthMode; + +struct _SalCertificatesChain; +typedef struct _SalCertificatesChain SalCertificatesChain; +struct _SalSigningKey; +typedef struct _SalSigningKey SalSigningKey; + +/** + * Format of certificate buffer + * */ +typedef enum SalCertificateRawFormat { + SAL_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/ + SAL_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/ +}SalCertificateRawFormat; + + + typedef struct SalAuthInfo{ char *username; char *userid; @@ -338,6 +361,9 @@ typedef struct SalAuthInfo{ char *realm; char *domain; char *ha1; + SalAuthMode mode; + SalSigningKey *key; + SalCertificatesChain *certificates; }SalAuthInfo; typedef struct SalBody{ @@ -424,6 +450,29 @@ SalAuthInfo* sal_auth_info_new(); SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info); void sal_auth_info_delete(SalAuthInfo* auth_info); LINPHONE_PUBLIC int sal_auth_compute_ha1(const char* userid,const char* realm,const char* password, char ha1[33]); +SalAuthMode sal_auth_info_get_mode(const SalAuthInfo* auth_info); +SalSigningKey *sal_auth_info_get_signing_key(const SalAuthInfo* auth_info); +SalCertificatesChain *sal_auth_info_get_certificates_chain(const SalAuthInfo* auth_info); +void sal_auth_info_set_mode(SalAuthInfo* auth_info, SalAuthMode mode); + +/** Parse a file containing either a certificate chain order in PEM format or a single DER cert + * @param auth_info structure where to store the result of parsing + * @param path path to certificate chain file + * @param format either PEM or DER + */ +void sal_certificates_chain_parse_file(SalAuthInfo* auth_info, const char* path, SalCertificateRawFormat format); + +/** + * Parse a file containing either a private or public rsa key + * @param auth_info structure where to store the result of parsing + * @param passwd password (optionnal) + */ +void sal_signing_key_parse_file(SalAuthInfo* auth_info, const char* path, const char *passwd); + +void sal_certificates_chain_delete(SalCertificatesChain *chain); +void sal_signing_key_delete(SalSigningKey *key); + + void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs); int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure); From edfc32db242b0b25b12c2d539bac197d894f514c Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 21 Nov 2013 13:53:29 +0100 Subject: [PATCH 13/38] Show registration refresher in UI --- gtk/main.ui | 1 + 1 file changed, 1 insertion(+) diff --git a/gtk/main.ui b/gtk/main.ui index dde462ec3..ae1335c5d 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1548,6 +1548,7 @@ True + True True False none From fd06569c8ad46117560f35c7b3d4cf805b7ec004 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 21 Nov 2013 13:53:39 +0100 Subject: [PATCH 14/38] git ignore --- .gitignore | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.gitignore b/.gitignore index 9dd415435..0512fc3df 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,19 @@ coreapi/test_ecc coreapi/test_lsd gtk/version_date.h specs.c +*.orig +*.rej +*.kdev4 +*.lo +*.la +*.swp +.deps +.libs +coreapi/test_numbers +coreapi/help/notify +share/fresh-rootca.pem +share/certdata.txt +tester/liblinphone_tester +tools/lp-gen-wrappers +tools/lpc2xml_test +tools/xml2lpc_test From 9c955aed326c4a939f769979374ce7d14b6847ea Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 21 Nov 2013 15:50:31 +0100 Subject: [PATCH 15/38] Fix a few leaks. --- coreapi/bellesip_sal/sal_impl.c | 2 +- coreapi/linphonecore.c | 4 +++- coreapi/sal.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index af7d077c7..d73142e71 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -483,9 +483,9 @@ void sal_uninit(Sal* sal){ belle_sip_object_unref(sal->prov); belle_sip_object_unref(sal->stack); belle_sip_object_unref(sal->listener); + if (sal->uuid) ms_free(sal->uuid); if (sal->root_ca) ms_free(sal->root_ca); ms_free(sal); - return ; }; int sal_add_listen_port(Sal *ctx, SalAddress* addr){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 33f30c32e..50adc5007 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5651,7 +5651,9 @@ static void linphone_core_uninit(LinphoneCore *lc) if(lc->rec_file!=NULL){ ms_free(lc->rec_file); } - + if(lc->presence_model){ + linphone_presence_model_unref(lc->presence_model); + } linphone_core_free_payload_types(lc); linphone_core_message_storage_close(lc); diff --git a/coreapi/sal.c b/coreapi/sal.c index 69ee5b6c2..7d471a7c8 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -483,6 +483,7 @@ void sal_auth_info_delete(SalAuthInfo* auth_info) { if (auth_info->realm) ms_free(auth_info->realm); if (auth_info->domain) ms_free(auth_info->domain); if (auth_info->password) ms_free(auth_info->password); + if (auth_info->ha1) ms_free(auth_info->ha1); if (auth_info->certificates) sal_certificates_chain_delete(auth_info->certificates); if (auth_info->key) sal_signing_key_delete(auth_info->key); ms_free(auth_info); From c45e8dfbeff127b0caa5814a0885de089da339c7 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Thu, 21 Nov 2013 15:50:58 +0100 Subject: [PATCH 16/38] Newer mediastreamer compiling on Jessie. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index c1be4195c..5c33fb5f9 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c1be4195ccc127199d3541a7a5e7ce0351fcde63 +Subproject commit 5c33fb5f9d9a9ccfe8f620ba0f9ead009d9bb402 From 1bf1ee2aba2863767f3d85a9d3ebcff8b7b0638e Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 21 Nov 2013 15:53:35 +0100 Subject: [PATCH 17/38] rename cacert.pem to cafile.pem to be consistent with flexisip usage --- .../certificates/altname/{cacert.pem => cafile.pem} | 0 tester/certificates/cn/{cacert.pem => cafile.pem} | 0 tester/liblinphone_tester.c | 12 ++++++++---- tester/register_tester.c | 6 +++--- tester/tester_hosts | 2 +- 5 files changed, 12 insertions(+), 8 deletions(-) rename tester/certificates/altname/{cacert.pem => cafile.pem} (100%) rename tester/certificates/cn/{cacert.pem => cafile.pem} (100%) diff --git a/tester/certificates/altname/cacert.pem b/tester/certificates/altname/cafile.pem similarity index 100% rename from tester/certificates/altname/cacert.pem rename to tester/certificates/altname/cafile.pem diff --git a/tester/certificates/cn/cacert.pem b/tester/certificates/cn/cafile.pem similarity index 100% rename from tester/certificates/cn/cacert.pem rename to tester/certificates/cn/cafile.pem diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 6be3bd70b..a240bb3f6 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -108,9 +108,9 @@ static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* sal_enable_test_features(lc->sal,TRUE); #ifndef ANDROID - snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cn/cacert.pem", path); + snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cn/cafile.pem", path); #else - snprintf(rootcapath, sizeof(rootcapath), "%s/cacert.pem", path); + snprintf(rootcapath, sizeof(rootcapath), "%s/cafile.pem", path); #endif linphone_core_set_root_ca(lc,rootcapath); @@ -182,7 +182,7 @@ LinphoneCoreManager *get_manager(LinphoneCore *lc){ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies) { LinphoneCoreManager* mgr= ms_new0(LinphoneCoreManager,1); LinphoneProxyConfig* proxy; - int proxy_count=check_for_proxies?(rc_file?1:0):0; + int proxy_count; int retry=0; mgr->v_table.registration_state_changed=registration_state_changed; @@ -201,8 +201,12 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f linphone_core_set_user_data(mgr->lc,mgr); reset_counters(&mgr->stat); /*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/ + if (check_for_proxies && rc_file) /**/ + proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)); + else + proxy_count=0; - while (mgr->stat.number_of_LinphoneRegistrationOkstat.number_of_LinphoneRegistrationOk2?(proxy_count-2)*10:0))) { linphone_core_iterate(mgr->lc); ms_usleep(100000); } diff --git a/tester/register_tester.c b/tester/register_tester.c index adf3197a8..9531c1447 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -537,7 +537,7 @@ static void tls_certificate_failure(){ linphone_core_set_root_ca(mgr->lc,NULL); /*no root ca*/ linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationFailed,2)); - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cacert.pem", liblinphone_tester_file_prefix); /*goot root ca*/ + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); /*goot root ca*/ linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); @@ -575,7 +575,7 @@ static void tls_alt_name_register(){ mgr=linphone_core_manager_new2("pauline_alt_rc",FALSE); lc=mgr->lc; - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cacert.pem", liblinphone_tester_file_prefix); + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,1)); @@ -590,7 +590,7 @@ static void tls_wildcard_register(){ mgr=linphone_core_manager_new2("pauline_wild_rc",FALSE); lc=mgr->lc; - snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cacert.pem", liblinphone_tester_file_prefix); + snprintf(rootcapath,sizeof(rootcapath), "%s/certificates/cn/cafile.pem", liblinphone_tester_file_prefix); linphone_core_set_root_ca(mgr->lc,rootcapath); linphone_core_refresh_registers(mgr->lc); CU_ASSERT_TRUE(wait_for(lc,lc,&mgr->stat.number_of_LinphoneRegistrationOk,2)); diff --git a/tester/tester_hosts b/tester/tester_hosts index b7056b863..de1edc48c 100644 --- a/tester/tester_hosts +++ b/tester/tester_hosts @@ -1 +1 @@ -94.23.19.176 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org +127.0.0.1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org From e0256b1f7a306bb3f440517afb96674c0d37e998 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 21 Nov 2013 16:26:44 +0100 Subject: [PATCH 18/38] fix compilation issue --- .cproject | 2 +- coreapi/bellesip_sal/sal_impl.c | 4 ++-- include/sal/sal.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.cproject b/.cproject index d4a5780c3..51c77f8e9 100644 --- a/.cproject +++ b/.cproject @@ -22,7 +22,7 @@ - + diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index d73142e71..80f577490 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -705,7 +705,7 @@ SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) { auth_info->realm = ms_strdup(belle_sip_auth_event_get_realm(event)); auth_info->username = ms_strdup(belle_sip_auth_event_get_username(event)); auth_info->domain = ms_strdup(belle_sip_auth_event_get_domain(event)); - auth_info->mode = belle_sip_auth_event_get_mode(event); + auth_info->mode = (SalAuthMode)belle_sip_auth_event_get_mode(event); return auth_info; } @@ -877,7 +877,7 @@ void sal_enable_unconditional_answer(Sal *sal,int value) { * @param format either PEM or DER */ void sal_certificates_chain_parse_file(SalAuthInfo* auth_info, const char* path, SalCertificateRawFormat format) { - auth_info->certificates = (SalCertificatesChain*) belle_sip_certificates_chain_parse_file(path, format); // + auth_info->certificates = (SalCertificatesChain*) belle_sip_certificates_chain_parse_file(path, (belle_sip_certificate_raw_format_t)format); // if (auth_info->certificates) belle_sip_object_ref((belle_sip_object_t *) auth_info->certificates); } diff --git a/include/sal/sal.h b/include/sal/sal.h index 86f20c60d..70146cd05 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -334,7 +334,7 @@ typedef enum SalTextDeliveryStatus{ /** * auth event mode * */ -typedef enum SalAuthMode { +typedef enum SalAuthMode { /*this enum must be same as belle_sip_auth_mode_t*/ SalAuthModeHttpDigest, /** Digest authentication requested*/ SalAuthModeTls /** Client certificate requested*/ }SalAuthMode; @@ -347,7 +347,7 @@ typedef struct _SalSigningKey SalSigningKey; /** * Format of certificate buffer * */ -typedef enum SalCertificateRawFormat { +typedef enum SalCertificateRawFormat {/*this enum must be same as belle_sip_certificate_raw_format_t*/ SAL_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/ SAL_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/ }SalCertificateRawFormat; From fb4939e20d2c165c24e3e9264d3caa2cb3e18d25 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 22 Nov 2013 09:26:24 +0100 Subject: [PATCH 19/38] revert ffmpeg api changes in Ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 5c33fb5f9..46b7347dd 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 5c33fb5f9d9a9ccfe8f620ba0f9ead009d9bb402 +Subproject commit 46b7347dd2a3695eafbd24d1f4223b148bfccfb2 From 1c94770d5534875f873ab36b5374bfe481188831 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Fri, 22 Nov 2013 15:12:39 +0100 Subject: [PATCH 20/38] Fix likely leak --- coreapi/chat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/chat.c b/coreapi/chat.c index d220b0119..c2e6a9cf5 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -95,6 +95,7 @@ void linphone_chat_room_destroy(LinphoneChatRoom *cr){ lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr); linphone_address_destroy(cr->peer_url); ms_free(cr->peer); + ms_free(cr); } From bc6a5f7237b6c51aacde5b29e6f961850ea48801 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 22 Nov 2013 15:49:55 +0100 Subject: [PATCH 21/38] Add back ffmpeg improvements --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 46b7347dd..235af3130 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 46b7347dd2a3695eafbd24d1f4223b148bfccfb2 +Subproject commit 235af3130296b7e498d48aee0483661dfee6a10b From 4ddeb921c1360f6c78753a49a0931eafcc9de4f0 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 22 Nov 2013 16:35:20 +0100 Subject: [PATCH 22/38] tune routing of outgoing requests: - do not set the transport in the request-uri, it might confuse servers. - don't route sips request through tcp or udp --- coreapi/bellesip_sal/sal_op_impl.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 02cb90a1f..4c6a1091a 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -220,13 +220,13 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req belle_sip_uri_t* outbound_proxy=NULL; belle_sip_header_contact_t* contact; int result =-1; + belle_sip_uri_t *next_hop_uri=NULL; _sal_op_add_custom_headers(op, (belle_sip_message_t*)request); if (!op->dialog || belle_sip_dialog_get_state(op->dialog) == BELLE_SIP_DIALOG_NULL) { /*don't put route header if dialog is in confirmed state*/ const MSList *elem=sal_op_get_route_addresses(op); - belle_sip_uri_t *next_hop_uri; const char *transport; const char *method=belle_sip_request_get_method(request); @@ -234,24 +234,25 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data); next_hop_uri=outbound_proxy; }else{ - next_hop_uri=belle_sip_request_get_uri(request); + next_hop_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request)); } transport=belle_sip_uri_get_transport_param(next_hop_uri); if (transport==NULL){ /*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use * the first available transport*/ - if (belle_sip_provider_get_listening_point(prov,"UDP")==0){ - if (belle_sip_provider_get_listening_point(prov,"TCP")!=NULL){ - transport="tcp"; - }else if (belle_sip_provider_get_listening_point(prov,"TLS")!=NULL){ - transport="tls"; + if (!belle_sip_uri_is_secure(next_hop_uri)){ + if (belle_sip_provider_get_listening_point(prov,"UDP")==0){ + if (belle_sip_provider_get_listening_point(prov,"TCP")!=NULL){ + transport="tcp"; + }else if (belle_sip_provider_get_listening_point(prov,"TLS")!=NULL ){ + transport="tls"; + } + } + if (transport){ + belle_sip_message("Transport is not specified, using %s because UDP is not available.",transport); + belle_sip_uri_set_transport_param(next_hop_uri,transport); } } - if (transport){ - belle_sip_message("Transport is not specified, using %s because UDP is not available.",transport); - belle_sip_uri_set_transport_param(next_hop_uri,transport); - } - /* not really usefull belle_sip_uri_fix(next_hop_uri);*/ } if ((strcmp(method,"REGISTER")==0 || strcmp(method,"SUBSCRIBE")==0) && transport && (strcasecmp(transport,"TCP")==0 || strcasecmp(transport,"TLS")==0)){ @@ -279,7 +280,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req /*hmm just in case we already have authentication param in cache*/ belle_sip_provider_add_authorization(op->base.root->prov,request,NULL,NULL); } - result = belle_sip_client_transaction_send_request_to(client_transaction,outbound_proxy/*might be null*/); + result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/); /*update call id if not set yet for this OP*/ if (result == 0 && !op->base.call_id) { From f3041fc4f4b4874d4ecc7983cc1defaa8302a638 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 24 Nov 2013 18:27:17 +0100 Subject: [PATCH 23/38] update ms2 for ffmpeg compilation bugfixes --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 235af3130..cc3e27946 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 235af3130296b7e498d48aee0483661dfee6a10b +Subproject commit cc3e279462ea55cfd1f61e9ec79a3f3dce5e2121 From f885ec643a338313a9912e3cfe99dbab152f80e9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 25 Nov 2013 10:49:30 +0100 Subject: [PATCH 24/38] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index cc3e27946..f4b7da643 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit cc3e279462ea55cfd1f61e9ec79a3f3dce5e2121 +Subproject commit f4b7da643bb2fa78adfd9ce5ced23a7fbf262565 From f7cf5671357d28ab2f1f386792e42620bce1d4e2 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Tue, 26 Nov 2013 14:06:25 +0100 Subject: [PATCH 25/38] Added a flag to force inclusion of contact headers in ringing responses. The flag is SAL_OP_CALL_FORCE_CONTACT_IN_RINGING . This helps handling older versions of SIP servers that expect it to be present in the 183 response. --- coreapi/bellesip_sal/sal_op_call.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 08059fb22..dc8618020 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -603,10 +603,17 @@ int sal_call_notify_ringing(SalOp *op, bool_t early_media){ if (require) tags=belle_sip_header_get_unparsed_value(require); /* if client requires 100rel, then add necessary stuff*/ if (tags && strstr(tags,"100rel")!=0) { - belle_sip_header_address_t* contact= (belle_sip_header_address_t*)sal_op_get_contact_address(op); - belle_sip_header_contact_t* contact_header; + belle_sip_message_add_header((belle_sip_message_t*)ringing_response,BELLE_SIP_HEADER(belle_sip_header_extension_create("Require","100rel"))); belle_sip_message_add_header((belle_sip_message_t*)ringing_response,BELLE_SIP_HEADER(belle_sip_header_extension_create("RSeq","1"))); + } + +#ifndef SAL_OP_CALL_FORCE_CONTACT_IN_RINGING + if (tags && strstr(tags,"100rel")!=0) +#endif + { + belle_sip_header_address_t* contact= (belle_sip_header_address_t*)sal_op_get_contact_address(op); + belle_sip_header_contact_t* contact_header; if (contact && (contact_header=belle_sip_header_contact_create(contact))) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(ringing_response),BELLE_SIP_HEADER(contact_header)); } From fa16748aa61f402489d1fd1f4ebd5d3bdcb3bc4f Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Wed, 27 Nov 2013 09:18:32 +0100 Subject: [PATCH 26/38] Update mediastreamer to fix an AudioUnit problem on early media --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index f4b7da643..9a7e57405 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit f4b7da643bb2fa78adfd9ce5ced23a7fbf262565 +Subproject commit 9a7e57405031f92e2a46c294592bd89ec41ef25a From c6ceda063e109bc980aa95ae8bc88b9f1aeb711b Mon Sep 17 00:00:00 2001 From: Margaux Clerc Date: Wed, 27 Nov 2013 16:24:59 +0100 Subject: [PATCH 27/38] Update Mediastreamer2 Add flag to compile with contact header in android --- build/android/Android.mk | 4 ++++ mediastreamer2 | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build/android/Android.mk b/build/android/Android.mk index 235056c54..e9c9fa1f6 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -85,6 +85,10 @@ LOCAL_CFLAGS += -DHAVE_X264 endif endif +ifeq ($(BUILD_CONTACT_HEADER),1) +LOCAL_CFLAGS += -DSAL_OP_CALL_FORCE_CONTACT_IN_RINGING +endif + ifeq ($(USE_JAVAH),1) LOCAL_CFLAGS += -DUSE_JAVAH endif diff --git a/mediastreamer2 b/mediastreamer2 index 9a7e57405..f8cba9686 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 9a7e57405031f92e2a46c294592bd89ec41ef25a +Subproject commit f8cba968622ce3400d2c67bfb8a248ef48363627 From 41f0390f931534f9ae4872816e1449c354b79bf5 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 27 Nov 2013 16:48:57 +0100 Subject: [PATCH 28/38] generate SRTP keys more securely simplify management of SalMediaDescription take into account changes in local encryption keys while updating streams. --- coreapi/bellesip_sal/sal_impl.c | 5 ++++ coreapi/callbacks.c | 42 ++++++--------------------- coreapi/linphonecall.c | 50 ++++++++++++++++++--------------- coreapi/private.h | 2 ++ include/sal/sal.h | 6 +++- 5 files changed, 47 insertions(+), 58 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 80f577490..e69359e9c 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -890,3 +890,8 @@ void sal_signing_key_parse_file(SalAuthInfo* auth_info, const char* path, const auth_info->key = (SalSigningKey *) belle_sip_signing_key_parse_file(path, passwd); if (auth_info->key) belle_sip_object_ref((belle_sip_object_t *) auth_info->key); } + +unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){ + return belle_sip_random_bytes(ret,size); +} + diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index ee125717f..183371130 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -37,24 +37,16 @@ static void register_failure(SalOp *op, SalError error, SalReason reason, const static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) { if (call->params.in_conference != call->current_params.in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED; if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_CHANGED; - return sal_media_description_equals(oldmd, newmd); + if (call->localdesc_changed) ms_message("Local description has changed: %i", call->localdesc_changed); + return call->localdesc_changed | sal_media_description_equals(oldmd, newmd); } void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) { - SalStreamDescription *old_audiodesc = NULL; - SalStreamDescription *old_videodesc = NULL; SalStreamDescription *new_audiodesc = NULL; SalStreamDescription *new_videodesc = NULL; char *rtp_addr, *rtcp_addr; int i; - for (i = 0; i < old_md->n_active_streams; i++) { - if (old_md->streams[i].type == SalAudio) { - old_audiodesc = &old_md->streams[i]; - } else if (old_md->streams[i].type == SalVideo) { - old_videodesc = &old_md->streams[i]; - } - } for (i = 0; i < new_md->n_active_streams; i++) { if (new_md->streams[i].type == SalAudio) { new_audiodesc = &new_md->streams[i]; @@ -76,21 +68,6 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c rtp_session_set_remote_addr_full(call->videostream->ms.session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port); } #endif - - /* Copy address and port values from new_md to old_md since we will keep old_md as resultdesc */ - strcpy(old_md->addr, new_md->addr); - if (old_audiodesc && new_audiodesc) { - strcpy(old_audiodesc->rtp_addr, new_audiodesc->rtp_addr); - strcpy(old_audiodesc->rtcp_addr, new_audiodesc->rtcp_addr); - old_audiodesc->rtp_port = new_audiodesc->rtp_port; - old_audiodesc->rtcp_port = new_audiodesc->rtcp_port; - } - if (old_videodesc && new_videodesc) { - strcpy(old_videodesc->rtp_addr, new_videodesc->rtp_addr); - strcpy(old_videodesc->rtcp_addr, new_videodesc->rtcp_addr); - old_videodesc->rtp_port = new_videodesc->rtp_port; - old_videodesc->rtcp_port = new_videodesc->rtcp_port; - } } void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){ @@ -112,9 +89,6 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ms_message("Media descriptions are different, need to restart the streams."); } else { if (md_changed == SAL_MEDIA_DESCRIPTION_UNCHANGED) { - /*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 */ @@ -127,7 +101,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia #endif } ms_message("No need to restart streams, SDP is unchanged."); - return; + goto end; }else { if (md_changed & SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED) { ms_message("Network parameters have changed, update them."); @@ -137,17 +111,13 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ms_message("Crypto parameters have changed, update them."); linphone_call_update_crypto_parameters(call, oldmd, new_md); } - call->resultdesc = oldmd; - sal_media_description_unref(new_md); - return; + goto end; } } } linphone_call_stop_media_streams (call); linphone_call_init_media_streams (call); } - if (oldmd) - sal_media_description_unref(oldmd); if (new_md) { bool_t all_muted=FALSE; @@ -169,6 +139,10 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){ linphone_core_play_named_tone(lc,LinphoneToneCallOnHold); } + end: + if (oldmd) + sal_media_description_unref(oldmd); + } #if 0 static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 6786209cd..82274f22d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -43,24 +43,34 @@ static MSWebCam *get_nowebcam_device(){ } #endif -static bool_t generate_b64_crypto_key(int key_length, char* key_out) { +static bool_t generate_b64_crypto_key(int key_length, char* key_out, size_t key_out_size) { int b64_size; - uint8_t* tmp = (uint8_t*) malloc(key_length); - if (ortp_crypto_get_random(tmp, key_length)!=0) { + uint8_t* tmp = (uint8_t*) ms_malloc0(key_length); + if (sal_get_random_bytes(tmp, key_length)==NULL) { ms_error("Failed to generate random key"); - free(tmp); + ms_free(tmp); return FALSE; } b64_size = b64_encode((const char*)tmp, key_length, NULL, 0); + if (b64_size == 0) { + ms_error("Failed to get b64 result size"); + ms_free(tmp); + return FALSE; + } + if (b64_size>=key_out_size){ + ms_error("Insufficient room for writing base64 SRTP key"); + ms_free(tmp); + return FALSE; + } + b64_size=b64_encode((const char*)tmp, key_length, key_out, key_out_size); if (b64_size == 0) { ms_error("Failed to b64 encode key"); - free(tmp); + ms_free(tmp); return FALSE; } key_out[b64_size] = '\0'; - b64_encode((const char*)tmp, key_length, key_out, 40); - free(tmp); + ms_free(tmp); return TRUE; } @@ -293,17 +303,18 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * if (md->streams[i].proto == SalProtoRtpSavp) { if (keep_srtp_keys && old_md && old_md->streams[i].proto==SalProtoRtpSavp){ int j; + ms_message("Keeping same crypto keys."); for(j=0;jstreams[i].crypto[j],&old_md->streams[i].crypto[j],sizeof(SalSrtpCryptoAlgo)); } }else{ md->streams[i].crypto[0].tag = 1; md->streams[i].crypto[0].algo = AES_128_SHA1_80; - if (!generate_b64_crypto_key(30, md->streams[i].crypto[0].master_key)) + if (!generate_b64_crypto_key(30, md->streams[i].crypto[0].master_key, SAL_SRTP_KEY_SIZE)) md->streams[i].crypto[0].algo = 0; md->streams[i].crypto[1].tag = 2; md->streams[i].crypto[1].algo = AES_128_SHA1_32; - if (!generate_b64_crypto_key(30, md->streams[i].crypto[1].master_key)) + if (!generate_b64_crypto_key(30, md->streams[i].crypto[1].master_key, SAL_SRTP_KEY_SIZE)) md->streams[i].crypto[1].algo = 0; md->streams[i].crypto[2].algo = 0; } @@ -322,7 +333,10 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * #endif //BUILD_UPNP linphone_address_destroy(addr); call->localdesc=md; - if (old_md) sal_media_description_unref(old_md); + if (old_md){ + call->localdesc_changed=sal_media_description_equals(md,old_md); + sal_media_description_unref(old_md); + } } static int find_port_offset(LinphoneCore *lc, SalStreamType type){ @@ -1538,6 +1552,9 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m for(elem=desc->payloads;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; int number; + /* make a copy of the payload type, so that we left the ones from the SalStreamDescription unchanged. + If the SalStreamDescription is freed, this will have no impact on the running streams*/ + pt=payload_type_clone(pt); if ((pt->flags & PAYLOAD_TYPE_FLAG_CAN_SEND) && first) { if (desc->type==SalAudio){ @@ -1926,7 +1943,6 @@ void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call){ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md) { SalStreamDescription *old_stream; SalStreamDescription *new_stream; - int i; old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalAudio); new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalAudio); @@ -1941,11 +1957,6 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag); call->audiostream_encrypted = FALSE; } - for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) { - old_stream->crypto[i].tag = new_stream->crypto[i].tag; - old_stream->crypto[i].algo = new_stream->crypto[i].algo; - strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1); - } } } @@ -1963,11 +1974,6 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag); call->videostream_encrypted = FALSE; } - for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) { - old_stream->crypto[i].tag = new_stream->crypto[i].tag; - old_stream->crypto[i].algo = new_stream->crypto[i].algo; - strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1); - } } } #endif @@ -2057,12 +2063,10 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ ms_event_queue_skip(call->core->msevq); } if (call->audio_profile){ - rtp_profile_clear_all(call->audio_profile); rtp_profile_destroy(call->audio_profile); call->audio_profile=NULL; } if (call->video_profile){ - rtp_profile_clear_all(call->video_profile); rtp_profile_destroy(call->video_profile); call->video_profile=NULL; } diff --git a/coreapi/private.h b/coreapi/private.h index 69eead0f1..e4ddd59c0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -199,6 +199,8 @@ struct _LinphoneCall unsigned int remote_session_ver; LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/ LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */ + int localdesc_changed; + bool_t refer_pending; bool_t media_pending; bool_t audio_muted; diff --git a/include/sal/sal.h b/include/sal/sal.h index 70146cd05..046f2928f 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -169,11 +169,13 @@ typedef struct SalIceRemoteCandidate { #define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256 #define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256 +#define SAL_SRTP_KEY_SIZE 41 + typedef struct SalSrtpCryptoAlgo { unsigned int tag; enum ortp_srtp_crypto_suite_t algo; /* 41= 40 max(key_length for all algo) + '\0' */ - char master_key[41]; + char master_key[SAL_SRTP_KEY_SIZE]; } SalSrtpCryptoAlgo; #define SAL_CRYPTO_ALGO_MAX 4 @@ -687,4 +689,6 @@ LINPHONE_PUBLIC void sal_set_dns_timeout(Sal* sal,int timeout); LINPHONE_PUBLIC int sal_get_dns_timeout(const Sal* sal); LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file); LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal); +unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size); + #endif From a8d304fd8f5fb6224cffabfadf61fbef6ea0577e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 28 Nov 2013 11:59:35 +0100 Subject: [PATCH 29/38] * implement reporting of dtmf received via SIP info * dtmf can be typed on keyboard with gtk app. --- coreapi/bellesip_sal/sal_impl.c | 2 ++ coreapi/bellesip_sal/sal_op_call.c | 14 +++++--- coreapi/callbacks.c | 2 ++ coreapi/sal.c | 55 ++++++++++++++++++++++++++++++ gtk/keypad.ui | 3 ++ gtk/main.c | 40 ++++++++++++++++++++++ include/sal/sal.h | 4 +++ mediastreamer2 | 2 +- 8 files changed, 116 insertions(+), 6 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index e69359e9c..2bfe23795 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -895,3 +895,5 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){ return belle_sip_random_bytes(ret,size); } + + diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index dc8618020..b434a1c38 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -362,7 +362,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } dialog_state=belle_sip_dialog_get_state(op->dialog); switch(dialog_state) { - case BELLE_SIP_DIALOG_NULL: { if (strcmp("INVITE",belle_sip_request_get_method(req))==0) { if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) { @@ -461,7 +460,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t }else{ SalBody salbody; if (sal_op_get_body(op,(belle_sip_message_t*)req,&salbody)) { - op->base.root->callbacks.info_received(op,&salbody); + if (sal_body_has_type(&salbody,"application","dtmf-relay")){ + char tmp[10]; + if (sal_lines_get_value(salbody.data, "Signal",tmp, sizeof(tmp))){ + op->base.root->callbacks.dtmf_received(op,tmp[0]); + } + }else + op->base.root->callbacks.info_received(op,&salbody); } else { op->base.root->callbacks.info_received(op,NULL); } @@ -485,10 +490,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t unsupported_method(server_transaction,req); } break; - default: { + default: ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state)); - } - /* no break */ + break; } if (server_transaction) belle_sip_object_unref(server_transaction); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 183371130..4c931cc33 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -67,6 +67,8 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c ms_message("Change video stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port); rtp_session_set_remote_addr_full(call->videostream->ms.session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port); } +#else + (void)new_videodesc; #endif } diff --git a/coreapi/sal.c b/coreapi/sal.c index 7d471a7c8..25fa8dcd8 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -26,6 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #endif #include "sal/sal.h" + +#include + const char* sal_transport_to_string(SalTransport transport) { switch (transport) { case SalTransportUDP:return "udp"; @@ -572,3 +575,55 @@ const char* sal_privacy_to_string(SalPrivacy privacy) { default: return NULL; } } + +static void remove_trailing_spaces(char *line){ + int i; + for(i=strlen(line)-1;i>=0;--i){ + if (isspace(line[i])) line[i]='\0'; + else break; + } +} + +static int line_get_value(const char *input, const char *key, char *value, size_t value_size, int *read){ + const char *end=strchr(input,'\n'); + char line[256]={0}; + char key_candidate[256]; + char *equal; + size_t len; + if (!end) len=strlen(input); + else len=end +1 -input; + *read=len; + strncpy(line,input,MIN(len,sizeof(line))); + equal=strchr(line,'='); + if (!equal) return FALSE; + *equal='\0'; + if (sscanf(line,"%s",key_candidate)!=1) return FALSE; + if (strcasecmp(key,key_candidate)==0){ + equal++; + remove_trailing_spaces(equal); + strncpy(value,equal,value_size-1); + value[value_size-1]='\0'; + return TRUE; + } + return FALSE; +} + +int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size){ + int read=0; + + do{ + if (line_get_value(data,key,value,value_size,&read)) + return TRUE; + data+=read; + }while(read!=0); + return FALSE; +} + +int sal_body_has_type(const SalBody *body, const char *type, const char *subtype){ + return body->type && body->subtype + && strcmp(body->type,type)==0 + && strcmp(body->subtype,subtype)==0; +} + + + diff --git a/gtk/keypad.ui b/gtk/keypad.ui index 6b5376762..5dfcfc487 100644 --- a/gtk/keypad.ui +++ b/gtk/keypad.ui @@ -8,8 +8,11 @@ True False + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK 0.5 none + + True diff --git a/gtk/main.c b/gtk/main.c index 87c278ddd..d8a8a2ede 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -64,6 +64,7 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl) static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg); static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token); static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate); +static void linphone_gtk_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf); void linphone_gtk_save_main_window_position(GtkWindow* mw, GdkEvent *event, gpointer data); static gboolean linphone_gtk_auto_answer(LinphoneCall *call); void linphone_gtk_status_icon_set_blinking(gboolean val); @@ -251,6 +252,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, vtable.buddy_info_updated=linphone_gtk_buddy_info_updated; vtable.call_encryption_changed=linphone_gtk_call_encryption_changed; vtable.transfer_state_changed=linphone_gtk_transfer_state_changed; + vtable.dtmf_received=linphone_gtk_dtmf_received; the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL); //lp_config_set_int(linphone_core_get_config(the_core), "sip", "store_auth_info", 0); @@ -1049,6 +1051,10 @@ static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm auth_timeout_new(w); } +static void linphone_gtk_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf){ + ms_message("Dtmf %c received.",dtmf); +} + static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){ GtkWidget *w=linphone_gtk_get_main_window(); GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar"); @@ -1715,6 +1721,40 @@ void linphone_gtk_init_dtmf_table(GtkWidget *mw){ g_object_set_data(G_OBJECT(linphone_gtk_get_widget(mw,"dtmf_*")),"label","*"); } +static gboolean key_allowed(guint32 code){ + static const char *allowed="1234567890#*ABCD"; + return code!=0 && strchr(allowed,(char)code)!=NULL; +} + +static GtkButton *get_button_from_key(GtkWidget *w, GdkEvent *event){ + guint keyval=event->key.keyval; + guint32 code=gdk_keyval_to_unicode(keyval); + code=g_unichar_toupper(code); + if (key_allowed(code)){ + char widgetname[16]; + w=gtk_widget_get_toplevel(w); + snprintf(widgetname,sizeof(widgetname),"dtmf_%c",code); + return GTK_BUTTON(linphone_gtk_get_widget(w,widgetname)); + } + return NULL; +} + +void linphone_gtk_keypad_key_pressed(GtkWidget *w, GdkEvent *event, gpointer userdata){ + GtkButton *button=get_button_from_key(w,event); + if (button) { + linphone_gtk_dtmf_pressed(button); + /*g_signal_emit_by_name(button, "button-press-event");*/ + } +} + +void linphone_gtk_keypad_key_released(GtkWidget *w, GdkEvent *event, gpointer userdata){ + GtkButton *button=get_button_from_key(w,event); + if (button) { + linphone_gtk_dtmf_released(button); + /*g_signal_emit_by_name(button, "button-release-event");*/ + } +} + void linphone_gtk_create_keypad(GtkWidget *button){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *k=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"keypad"); diff --git a/include/sal/sal.h b/include/sal/sal.h index 046f2928f..99b04fba8 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -691,4 +691,8 @@ LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_fil LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal); unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size); +int sal_body_has_type(const SalBody *body, const char *type, const char *subtype); +/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/ +int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size); + #endif diff --git a/mediastreamer2 b/mediastreamer2 index f8cba9686..25d5fc4a3 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit f8cba968622ce3400d2c67bfb8a248ef48363627 +Subproject commit 25d5fc4a3383c3eeb79193bb31f1d2f123246dfd From cfe2a94f6c5e53200c62c9ba1992961afc9f8038 Mon Sep 17 00:00:00 2001 From: Guillaume BIENKOWSKI Date: Thu, 28 Nov 2013 16:57:26 +0100 Subject: [PATCH 30/38] Fix sips handling in interpret_url. Added a unit test for it. --- coreapi/linphonecore.c | 4 ++-- tester/setup_tester.c | 26 +++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 50adc5007..de2061555 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2279,8 +2279,8 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url) enum_lookup_res_free(enumres); return uri; } - /* check if we have a "sip:" */ - if (strstr(url,"sip:")==NULL){ + /* check if we have a "sip:" or a "sips:" */ + if ( (strstr(url,"sip:")==NULL) && (strstr(url,"sips:")==NULL) ){ /* this doesn't look like a true sip uri */ if (strchr(url,'@')!=NULL){ /* seems like sip: is missing !*/ diff --git a/tester/setup_tester.c b/tester/setup_tester.c index 06949f82c..7a5bac9c9 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -68,11 +68,35 @@ static void core_sip_transport_test(void) { linphone_core_destroy(lc); } +static void linphone_interpret_url_test() +{ + LinphoneCoreVTable v_table; + LinphoneCore* lc; + const char* sips_address = "sips:margaux@sip.linphone.org"; + LinphoneAddress* address; + + memset ( &v_table,0,sizeof ( v_table ) ); + lc = linphone_core_new ( &v_table,NULL,NULL,NULL ); + CU_ASSERT_PTR_NOT_NULL_FATAL ( lc ); + + address = linphone_core_interpret_url(lc, sips_address); + + CU_ASSERT_PTR_NOT_NULL_FATAL(address); + CU_ASSERT_STRING_EQUAL_FATAL(linphone_address_get_scheme(address), "sips"); + CU_ASSERT_STRING_EQUAL_FATAL(linphone_address_get_username(address), "margaux"); + CU_ASSERT_STRING_EQUAL_FATAL(linphone_address_get_domain(address), "sip.linphone.org"); + + linphone_address_destroy(address); + + linphone_core_destroy ( lc ); +} + test_t setup_tests[] = { { "Linphone Address", linphone_address_test }, { "Linphone core init/uninit", core_init_test }, - { "Linphone random transport port",core_sip_transport_test} + { "Linphone random transport port",core_sip_transport_test}, + { "Linphone interpret url", linphone_interpret_url_test } }; test_suite_t setup_test_suite = { From d7beb3193bd6da62cac7850686297b505222c0c2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 28 Nov 2013 21:48:14 +0100 Subject: [PATCH 31/38] reset codecs in current call params when stream is ended, otherwise it points to undefined memory. --- coreapi/linphonecall.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 82274f22d..a952865ab 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -2038,6 +2038,7 @@ void linphone_call_stop_audio_stream(LinphoneCall *call) { } audio_stream_stop(call->audiostream); call->audiostream=NULL; + call->current_params.audio_codec = NULL; } } @@ -2051,6 +2052,7 @@ void linphone_call_stop_video_stream(LinphoneCall *call) { linphone_call_log_fill_stats(call->log,(MediaStream*)call->videostream); video_stream_stop(call->videostream); call->videostream=NULL; + call->current_params.video_codec = NULL; } #endif } @@ -2555,7 +2557,7 @@ bool_t linphone_call_is_in_conference(const LinphoneCall *call) { * @param cx a floating point number pointing the horizontal center of the zoom to be applied. This value should be between 0.0 and 1.0. * @param cy a floating point number pointing the vertical center of the zoom to be applied. This value should be between 0.0 and 1.0. * - * cx and cy are updated in return in case their coordinates were to excentrated for the requested zoom factor. The zoom ensures that all the screen is fullfilled with the video. + * cx and cy are updated in return in case their coordinates were too excentrated for the requested zoom factor. The zoom ensures that all the screen is fullfilled with the video. **/ void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy) { VideoStream* vstream = call->videostream; From fb54b4790bec2402b1fdb3f547d851af3c69dbc7 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 29 Nov 2013 18:20:44 +0100 Subject: [PATCH 32/38] update ms2 for multi linphonecore fixes --- coreapi/linphonecore.c | 4 ++-- mediastreamer2 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index de2061555..c19c5e094 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5502,7 +5502,7 @@ static void sound_config_uninit(LinphoneCore *lc) if (config->local_ring) ms_free(config->local_ring); if (config->remote_ring) ms_free(config->remote_ring); - ms_snd_card_manager_destroy(); + } static void video_config_uninit(LinphoneCore *lc) @@ -5657,7 +5657,7 @@ static void linphone_core_uninit(LinphoneCore *lc) linphone_core_free_payload_types(lc); linphone_core_message_storage_close(lc); - ortp_exit(); + ms_exit(); linphone_core_set_state(lc,LinphoneGlobalOff,"Off"); } diff --git a/mediastreamer2 b/mediastreamer2 index 25d5fc4a3..b2dc80f2d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 25d5fc4a3383c3eeb79193bb31f1d2f123246dfd +Subproject commit b2dc80f2de024dc8a40fc92043e63f4e4f0669aa From f72ac202cfaaeff2688c28031689c01a455f560d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 29 Nov 2013 19:17:48 +0100 Subject: [PATCH 33/38] fix build issue in ms2 --- coreapi/bellesip_sal/sal_impl.c | 13 +++++++++++++ mediastreamer2 | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 2bfe23795..abff14e99 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -488,6 +488,19 @@ void sal_uninit(Sal* sal){ ms_free(sal); }; +int sal_transport_available(Sal *sal, SalTransport t){ + switch(t){ + case SalTransportUDP: + case SalTransportTCP: + return TRUE; + case SalTransportTLS: + return belle_sip_stack_tls_available(sal->stack); + case SalTransportDTLS: + return FALSE; + } + return FALSE; +} + int sal_add_listen_port(Sal *ctx, SalAddress* addr){ int result; belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack diff --git a/mediastreamer2 b/mediastreamer2 index b2dc80f2d..75514ad53 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit b2dc80f2de024dc8a40fc92043e63f4e4f0669aa +Subproject commit 75514ad53cdda45632d35a474a2810e78b19997e From ab7e606d385a2835a6fbba71dc83fcbfac521368 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 29 Nov 2013 22:17:55 +0100 Subject: [PATCH 34/38] don't fail because no i-frame is received when video isn't enabled --- tester/call_tester.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tester/call_tester.c b/tester/call_tester.c index 8b984e498..8e5c952f7 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1027,9 +1027,10 @@ static void srtp_ice_call(void) { CU_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection)); check_rtcp(marie,pauline); -#endif /*wait for ice to found the direct path*/ CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_IframeDecoded,1)); +#endif + /*just to sleep*/ linphone_core_terminate_all_calls(marie->lc); From 6f9f860a2ef86dfb3e9f1a4020ab0b0f308058b9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 30 Nov 2013 11:25:55 +0100 Subject: [PATCH 35/38] allow multiple transports in gtk application, allow to configure transport per proxy (not yet finished) --- coreapi/address.c | 25 ++- coreapi/bellesip_sal/sal_address_impl.c | 20 ++- coreapi/linphonecore.c | 7 + coreapi/linphonecore.h | 18 +++ gtk/parameters.ui | 198 ++++++++++++++---------- gtk/propertybox.c | 160 ++++++++++--------- gtk/sip_account.ui | 89 +++++++---- include/sal/sal.h | 8 +- tester/tester_hosts | 2 +- 9 files changed, 331 insertions(+), 196 deletions(-) diff --git a/coreapi/address.c b/coreapi/address.c index bb50fe30a..ec37255c1 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -112,11 +112,21 @@ void linphone_address_set_domain(LinphoneAddress *uri, const char *host){ * Sets the port number. **/ void linphone_address_set_port(LinphoneAddress *uri, int port){ -#ifdef USE_BELLESIP sal_address_set_port(uri,port); -#else - sal_address_set_port_int(uri,port); -#endif +} + +/** + * Set a transport. +**/ +void linphone_address_set_transport(LinphoneAddress *uri, LinphoneTransportType tp){ + sal_address_set_transport(uri,(SalTransport)tp); +} + +/** + * Get the transport. +**/ +LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri){ + return (LinphoneTransportType)sal_address_get_transport(uri); } /** @@ -142,6 +152,13 @@ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ return sal_address_as_string_uri_only(u); } +/** + * Returns true if address refers to a secure location (sips) +**/ +bool_t linphone_address_is_secure(const LinphoneAddress *uri){ + return sal_address_is_secure(uri); +} + static bool_t strings_equals(const char *s1, const char *s2){ if (s1==NULL && s2==NULL) return TRUE; if (s1!=NULL && s2!=NULL && strcmp(s1,s2)==0) return TRUE; diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index 20da41fb2..4d124e140 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -43,6 +43,14 @@ const char *sal_address_get_scheme(const SalAddress *addr){ } else return NULL; } + +bool_t sal_address_is_secure(const SalAddress *addr){ + belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); + belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); + if (uri) return belle_sip_uri_is_secure(uri); + return FALSE; +} + const char *sal_address_get_display_name(const SalAddress* addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); return belle_sip_header_address_get_displayname(header_addr); @@ -52,17 +60,17 @@ const char *sal_address_get_display_name_unquoted(const SalAddress *addr){ return sal_address_get_display_name(addr); } #define SAL_ADDRESS_GET(addr,param) \ -belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\ +{belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\ belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\ if (uri) {\ return belle_sip_uri_get_##param(uri);\ } else\ - return NULL; + return NULL;} -#define SAL_ADDRESS_SET(addr,param,value) \ +#define SAL_ADDRESS_SET(addr,param,value) {\ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\ belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\ -belle_sip_uri_set_##param(uri,value); +belle_sip_uri_set_##param(uri,value);} const char *sal_address_get_username(const SalAddress *addr){ SAL_ADDRESS_GET(addr,user) @@ -137,7 +145,9 @@ void sal_address_set_param(SalAddress *addr,const char* name,const char* value){ } void sal_address_set_transport(SalAddress* addr,SalTransport transport){ - SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport)); + if (!sal_address_is_secure(addr)){ + SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport)); + } } void sal_address_set_transport_name(SalAddress* addr,const char *transport){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c19c5e094..33e7be9c3 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1892,6 +1892,13 @@ static int apply_transports(LinphoneCore *lc){ return 0; } +/** + * Returns TRUE if given transport type is supported by the library, FALSE otherwise. +**/ +bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp){ + return sal_transport_available(lc->sal,(SalTransport)tp); +} + /** * Sets the ports to be used for each of transport (UDP or TCP) * diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 9ba12e8e8..317f01875 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -89,6 +89,19 @@ typedef struct _LCSipTransports{ } LCSipTransports; +/** + * Enum describing transport type for LinphoneAddress. +**/ +enum _LinphoneTransportType{ + LinphoneTransportUdp, + LinphoneTransportTcp, + LinphoneTransportTls, + LinphoneTransportDtls +}; +/*this enum MUST be kept in sync with the SalTransport from sal.h*/ + +typedef enum _LinphoneTransportType LinphoneTransportType; + /** * Object that represents a SIP address. * @@ -191,6 +204,9 @@ LINPHONE_PUBLIC void linphone_address_set_domain(LinphoneAddress *uri, const cha LINPHONE_PUBLIC void linphone_address_set_port(LinphoneAddress *uri, int port); /*remove tags, params etc... so that it is displayable to the user*/ LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri); +LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *uri); +LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri); +LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,LinphoneTransportType type); LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u); LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u); LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2); @@ -1526,6 +1542,8 @@ LINPHONE_PUBLIC int linphone_core_get_sip_port(LinphoneCore *lc); LINPHONE_PUBLIC int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports *transports); LINPHONE_PUBLIC int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *transports); + +LINPHONE_PUBLIC bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp); /** * * Give access to the UDP sip socket. Can be useful to configure this socket as persistent I.E kCFStreamNetworkServiceType set to kCFStreamNetworkServiceTypeVoIP) diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 6624ec01c..4cb435eb2 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -48,6 +48,12 @@ 1 9.9999999995529656 + + 65535 + 5060 + 1 + 10 + 65535 2 @@ -324,23 +330,10 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 7 + 8 2 - - True - False - model8 - - - - 0 - - - - - - + True True @@ -350,6 +343,7 @@ True True adjustment7 + 1 @@ -363,8 +357,8 @@ Media encryption type - 3 - 5 + 4 + 6 @@ -376,24 +370,8 @@ 1 2 - 3 - 4 - - - - - gtk-edit - True - True - False - True - - - - 1 - 2 - 6 - 7 + 4 + 5 @@ -405,8 +383,8 @@ right - 2 - 3 + 3 + 4 @@ -418,36 +396,8 @@ right - 1 - 2 - - - - - True - False - DSCP fields - - - 5 - 6 - - - - - gtk-edit - True - True - True - False - True - - - - 1 - 2 - 5 - 6 + 2 + 3 @@ -513,8 +463,8 @@ 1 2 - 1 - 2 + 2 + 3 @@ -580,18 +530,8 @@ 1 2 - 2 - 3 - - - - - False - Tunnel - - - 6 - 7 + 3 + 4 @@ -607,10 +547,102 @@ 1 2 - 4 - 5 + 5 + 6 + + + False + Tunnel + + + 7 + 8 + + + + + gtk-edit + True + True + False + True + + + + 1 + 2 + 7 + 8 + + + + + True + False + DSCP fields + + + 6 + 7 + + + + + gtk-edit + True + True + True + False + True + + + + 1 + 2 + 6 + 7 + + + + + True + False + SIP/TCP port + + + 1 + 2 + + + + + True + True + + True + False + False + True + True + adjustment8 + + + + 1 + 2 + 1 + 2 + + + + + True + False + SIP/UDP port + + diff --git a/gtk/propertybox.c b/gtk/propertybox.c index bcdb52812..638f9955c 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -102,49 +102,6 @@ void linphone_gtk_update_my_contact(GtkWidget *w){ linphone_gtk_load_identities(); } -void linphone_gtk_update_my_port(GtkWidget *w){ - GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(w)); - LCSipTransports tr; - LinphoneCore *lc=linphone_gtk_get_core(); - GtkComboBox *combo = GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo")); - - gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - if (port == 1) { // We use default port if not specified - if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (UDP)") == 0) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), - 5060); - } - else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TCP)") == 0) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), - 5060); - } - else if (strcmp(gtk_combo_box_get_active_text(combo), "SIP (TLS)") == 0) { - gtk_spin_button_set_value(GTK_SPIN_BUTTON(w), - 5061); - } - } - - linphone_core_get_sip_transports(lc,&tr); - gchar *selected = gtk_combo_box_get_active_text(combo); - if (strcmp(selected, "SIP (TCP)") == 0) { - tr.tcp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - tr.udp_port = 0; - tr.tls_port = 0; - } - else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (UDP)") == 0) { - tr.udp_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - tr.tcp_port = 0; - tr.tls_port = 0; - } - else if (strcmp(gtk_combo_box_get_active_text(GTK_COMBO_BOX(linphone_gtk_get_widget(pb, "proto_combo"))), "SIP (TLS)") == 0){ - tr.udp_port = 0; - tr.tcp_port = 0; - tr.tls_port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(w)); - } - - linphone_core_set_sip_transports(lc,&tr); -} - void linphone_gtk_set_propety_entry(GtkWidget *w, gboolean stunServer, gboolean ip){ GtkWidget *stun_entry=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"stun_server"); GtkWidget *ip_entry=linphone_gtk_get_widget(gtk_widget_get_toplevel(w),"nat_address"); @@ -691,6 +648,48 @@ static void linphone_gtk_proxy_closed(GtkWidget *w){ } } +static void fill_transport_combo_box(GtkWidget *combo, LinphoneTransportType choice, gboolean is_sensitive){ + GtkTreeModel *model; + GtkTreeIter iter; + + if ((model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo)))==NULL){ + /*case where combo box is created with no model*/ + GtkCellRenderer *renderer=gtk_cell_renderer_text_new(); + model=GTK_TREE_MODEL(gtk_list_store_new(1,G_TYPE_STRING)); + gtk_combo_box_set_model(GTK_COMBO_BOX(combo),model); + gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE); + gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"markup",0,NULL); + } + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"UDP",-1); + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TCP",-1); + if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)){ + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TLS",-1); + } + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),(int)choice); + gtk_widget_set_sensitive(combo,is_sensitive); +} + +static void update_proxy_transport(GtkWidget *w){ + const char *addr=gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))); + LinphoneAddress *laddr=linphone_address_new(addr); + if (laddr){ + GtkWidget *combo=linphone_gtk_get_widget(w,"transport"); + if (linphone_address_is_secure(laddr)){ + fill_transport_combo_box(combo,LinphoneTransportTls,FALSE); + }else{ + fill_transport_combo_box(combo,linphone_address_get_transport(laddr),TRUE); + } + linphone_address_destroy(laddr); + } +} + +void linphone_gtk_proxy_address_changed(GtkEditable *editable){ + update_proxy_transport(gtk_widget_get_toplevel(GTK_WIDGET(editable))); +} + void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){ GtkWidget *w=linphone_gtk_create_window("sip_account"); const char *tmp; @@ -698,8 +697,7 @@ void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){ linphone_proxy_config_edit(cfg); gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")), linphone_proxy_config_get_identity(cfg)); - gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")), - linphone_proxy_config_get_addr(cfg)); + gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")),linphone_proxy_config_get_addr(cfg)); tmp=linphone_proxy_config_get_route(cfg); if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp); tmp=linphone_proxy_config_get_contact_parameters(cfg); @@ -901,14 +899,6 @@ void linphone_gtk_lang_changed(GtkComboBox *combo){ } } -void linphone_gtk_proto_changed(GtkComboBox *combo){ - GtkWidget *pb=gtk_widget_get_toplevel(GTK_WIDGET(combo)); - - GtkWidget *proto_port = linphone_gtk_get_widget(pb, "proto_port"); - // When we change the network protocol, we call update_my_port to move the port number from the old protocol to the new one - linphone_gtk_update_my_port(proto_port); -} - static void linphone_gtk_ui_level_adapt(GtkWidget *top) { gboolean ui_advanced; const char *simple_ui = linphone_gtk_get_ui_config("simple_ui", "parameters.codec_tab parameters.transport_frame parameters.ports_frame"); @@ -1074,6 +1064,48 @@ void linphone_gtk_fill_video_renderers(GtkWidget *pb){ if (active!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),active); } +typedef struct { + guint timeout_id; + LCSipTransports tp; +}PortConfigCtx; + +static void port_config_free(PortConfigCtx *ctx){ + g_free(ctx); +} + +static void apply_transports(PortConfigCtx *ctx){ + GtkWidget *mw=linphone_gtk_get_main_window(); + LCSipTransports tp; + LinphoneCore *lc=linphone_gtk_get_core(); + linphone_core_get_sip_transports(lc,&tp); + tp.udp_port=ctx->tp.udp_port; + tp.tcp_port=ctx->tp.tcp_port; + linphone_core_set_sip_transports(lc,&tp); + g_object_set_data(G_OBJECT(mw),"port_config",NULL); +} + +static void transport_changed(GtkWidget *parameters){ + GtkWidget *mw=linphone_gtk_get_main_window(); + PortConfigCtx *cfg=(PortConfigCtx*)g_object_get_data(G_OBJECT(mw),"port_config"); + if (cfg==NULL){ + cfg=g_new0(PortConfigCtx,1); + g_object_set_data_full(G_OBJECT(mw),"port_config",cfg,(GDestroyNotify)port_config_free); + } + if (cfg->timeout_id!=0) + g_source_remove(cfg->timeout_id); + cfg->tp.udp_port=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(linphone_gtk_get_widget(parameters,"sip_udp_port"))); + cfg->tp.tcp_port=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(linphone_gtk_get_widget(parameters,"sip_tcp_port"))); + cfg->timeout_id=g_timeout_add_seconds(2,(GSourceFunc)apply_transports,cfg); +} + +void linphone_gtk_udp_port_value_changed(GtkSpinButton *button){ + transport_changed(gtk_widget_get_toplevel((GtkWidget*)button)); +} + +void linphone_gtk_tcp_port_value_changed(GtkSpinButton *button){ + transport_changed(gtk_widget_get_toplevel((GtkWidget*)button)); +} + void linphone_gtk_show_parameters(void){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *pb=(GtkWidget*)g_object_get_data(G_OBJECT(mw),"parameters"); @@ -1101,21 +1133,11 @@ void linphone_gtk_show_parameters(void){ linphone_core_ipv6_enabled(lc)); linphone_core_get_sip_transports(lc,&tr); - if (tr.tcp_port > 0) { - gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 1); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")), - tr.tcp_port); - } - else if (tr.tls_port > 0) { - gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 2); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")), - tr.tls_port); - } - else { - gtk_combo_box_set_active(GTK_COMBO_BOX(linphone_gtk_get_widget(pb,"proto_combo")), 0); - gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"proto_port")), + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"sip_udp_port")), tr.udp_port); - } + gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"sip_tcp_port")), + tr.tcp_port); + linphone_core_get_audio_port_range(lc, &min_port, &max_port); gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb, "audio_min_rtp_port")), min_port); @@ -1214,10 +1236,6 @@ void linphone_gtk_show_parameters(void){ ui_advanced); linphone_gtk_ui_level_adapt(pb); - g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_port")),"value-changed",(GCallback)linphone_gtk_update_my_port,NULL); - g_signal_connect(G_OBJECT(linphone_gtk_get_widget(pb,"proto_combo")),"changed",(GCallback)linphone_gtk_proto_changed,NULL); - - if (linphone_core_tunnel_available()){ gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_edit_button")), TRUE); gtk_widget_set_visible(GTK_WIDGET(linphone_gtk_get_widget(pb,"tunnel_label")), TRUE); diff --git a/gtk/sip_account.ui b/gtk/sip_account.ui index 9c23c806d..d0a93d5dc 100644 --- a/gtk/sip_account.ui +++ b/gtk/sip_account.ui @@ -1,6 +1,7 @@ + 100000 3600 @@ -15,13 +16,13 @@ center-on-parent dialog - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 2 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -91,7 +92,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 + 6 2 @@ -112,6 +113,8 @@ sip: False False + True + True 1 @@ -140,6 +143,9 @@ sip: False False + True + True + 1 @@ -148,19 +154,6 @@ 2 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Route (optional): - right - - - 2 - 3 - - True @@ -168,12 +161,14 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False False + True + True 1 2 - 2 - 3 + 4 + 5 @@ -185,24 +180,26 @@ right - 3 - 4 + 2 + 3 True True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK False False + True + True adjustment1 1 2 - 3 - 4 + 2 + 3 @@ -210,12 +207,12 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Contact params: + Contact params (optional): right - 4 - 5 + 5 + 6 @@ -228,15 +225,53 @@ True False False + True + True 1 2 + 5 + 6 + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Route (optional): + right + + 4 5 - + + + True + False + Transport + + + 3 + 4 + + + + + True + False + + + + 1 + 2 + 3 + 4 + + True diff --git a/include/sal/sal.h b/include/sal/sal.h index 99b04fba8..6374e2a08 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -85,12 +85,9 @@ const char *sal_address_get_display_name(const SalAddress* addr); const 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); -#ifdef USE_BELLESIP int sal_address_get_port(const SalAddress *addr); -#else -const char * sal_address_get_port(const SalAddress *addr); -int sal_address_get_port_int(const SalAddress *addr); -#endif +bool_t sal_address_is_secure(const SalAddress *addr); + SalTransport sal_address_get_transport(const SalAddress* addr); const char* sal_address_get_transport_name(const SalAddress* addr); @@ -479,6 +476,7 @@ void sal_signing_key_delete(SalSigningKey *key); void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs); int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure); int sal_unlisten_ports(Sal *ctx); +int sal_transport_available(Sal *ctx, SalTransport t); void sal_set_dscp(Sal *ctx, int dscp); int sal_reset_transports(Sal *ctx); ortp_socket_t sal_get_socket(Sal *ctx); diff --git a/tester/tester_hosts b/tester/tester_hosts index de1edc48c..b7056b863 100644 --- a/tester/tester_hosts +++ b/tester/tester_hosts @@ -1 +1 @@ -127.0.0.1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org +94.23.19.176 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org From 8ffa2c38fee890450f05e9704fc02f4fb52ba066 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 1 Dec 2013 21:43:13 +0100 Subject: [PATCH 36/38] finish to implement multi transport in gtk app. fix malloc/free mismatch --- coreapi/bellesip_sal/sal_address_impl.c | 10 +++- gtk/propertybox.c | 63 +++++++++++++++++++++---- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index 4d124e140..91c2d91c8 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -129,13 +129,19 @@ void sal_address_clean(SalAddress *addr){ } char *sal_address_as_string(const SalAddress *addr){ - return belle_sip_object_to_string(BELLE_SIP_OBJECT(addr)); + char tmp[1024]={0}; + size_t off=0; + belle_sip_object_marshal((belle_sip_object_t*)addr,tmp,sizeof(tmp),&off); + return ms_strdup(tmp); } char *sal_address_as_string_uri_only(const SalAddress *addr){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); - return belle_sip_object_to_string(BELLE_SIP_OBJECT(uri)); + char tmp[1024]={0}; + size_t off=0; + belle_sip_object_marshal((belle_sip_object_t*)uri,tmp,sizeof(tmp),&off); + return ms_strdup(tmp); } void sal_address_set_param(SalAddress *addr,const char* name,const char* value){ diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 638f9955c..a3bcc4145 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -652,6 +652,8 @@ static void fill_transport_combo_box(GtkWidget *combo, LinphoneTransportType cho GtkTreeModel *model; GtkTreeIter iter; + if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(combo),"combo-updating"))) return; + if ((model=gtk_combo_box_get_model(GTK_COMBO_BOX(combo)))==NULL){ /*case where combo box is created with no model*/ GtkCellRenderer *renderer=gtk_cell_renderer_text_new(); @@ -660,13 +662,15 @@ static void fill_transport_combo_box(GtkWidget *combo, LinphoneTransportType cho gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo),renderer,TRUE); gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo),renderer,"markup",0,NULL); } - gtk_list_store_append(GTK_LIST_STORE(model),&iter); - gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"UDP",-1); - gtk_list_store_append(GTK_LIST_STORE(model),&iter); - gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TCP",-1); - if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)){ + if (!gtk_tree_model_get_iter_first(model,&iter)){ gtk_list_store_append(GTK_LIST_STORE(model),&iter); - gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TLS",-1); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"UDP",-1); + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TCP",-1); + if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)){ + gtk_list_store_append(GTK_LIST_STORE(model),&iter); + gtk_list_store_set(GTK_LIST_STORE(model),&iter,0,"TLS",-1); + } } gtk_combo_box_set_active(GTK_COMBO_BOX(combo),(int)choice); gtk_widget_set_sensitive(combo,is_sensitive); @@ -686,6 +690,31 @@ static void update_proxy_transport(GtkWidget *w){ } } +void linphone_gtk_proxy_transport_changed(GtkWidget *combo){ + GtkWidget *w=gtk_widget_get_toplevel(combo); + int index=gtk_combo_box_get_active(GTK_COMBO_BOX(combo)); + GtkWidget *proxy=linphone_gtk_get_widget(w,"proxy"); + const char *addr=gtk_entry_get_text(GTK_ENTRY(proxy)); + LinphoneAddress *laddr; + LinphoneTransportType new_transport=(LinphoneTransportType)index; + + if (index==-1) return; + + g_object_set_data(G_OBJECT(w),"combo-updating",GINT_TO_POINTER(1)); + laddr=linphone_address_new(addr); + if (laddr){ + if (linphone_address_get_transport(laddr)!=new_transport){ + char *newaddr; + linphone_address_set_transport(laddr,new_transport); + newaddr=linphone_address_as_string(laddr); + gtk_entry_set_text(GTK_ENTRY(proxy),newaddr); + ms_free(newaddr); + } + linphone_address_destroy(laddr); + } + g_object_set_data(G_OBJECT(w),"combo-updating",GINT_TO_POINTER(0)); +} + void linphone_gtk_proxy_address_changed(GtkEditable *editable){ update_proxy_transport(gtk_widget_get_toplevel(GTK_WIDGET(editable))); } @@ -723,15 +752,33 @@ void linphone_gtk_proxy_cancel(GtkButton *button){ void linphone_gtk_proxy_ok(GtkButton *button){ GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button)); LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config"); + int index=gtk_combo_box_get_active(GTK_COMBO_BOX(linphone_gtk_get_widget(w,"transport"))); gboolean was_editing=TRUE; + if (!cfg){ was_editing=FALSE; cfg=linphone_proxy_config_new(); } linphone_proxy_config_set_identity(cfg, gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")))); - linphone_proxy_config_set_server_addr(cfg, - gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy")))); + if (linphone_proxy_config_set_server_addr(cfg, + gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))))==0){ + if (index!=-1){ + /*make sure transport was added to proxy address*/ + LinphoneTransportType tport=(LinphoneTransportType)index; + LinphoneAddress *laddr=linphone_address_new(linphone_proxy_config_get_addr(cfg)); + if (laddr){ + if (linphone_address_get_transport(laddr)!=tport){ + char *tmp; + linphone_address_set_transport(laddr,tport); + tmp=linphone_address_as_string(laddr); + linphone_proxy_config_set_server_addr(cfg,tmp); + ms_free(tmp); + } + linphone_address_destroy(laddr); + } + } + } linphone_proxy_config_set_route(cfg, gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")))); linphone_proxy_config_set_contact_parameters(cfg, From 52226a4b993d9f48614d5f4cc5ec6dc8206fc283 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 1 Dec 2013 22:03:24 +0100 Subject: [PATCH 37/38] GTK app: enable TLS transport if tls is requested on a proxy config. --- coreapi/linphonecore.c | 4 ---- gtk/propertybox.c | 14 +++++++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 33e7be9c3..9bafb93da 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2412,11 +2412,7 @@ static MSList *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneA if (transport){ SalAddress *route=sal_address_new(NULL); sal_address_set_domain(route,sal_address_get_domain((SalAddress*)dest)); -#ifdef USE_BELLESIP sal_address_set_port(route,sal_address_get_port((SalAddress*)dest)); -#else - sal_address_set_port_int(route,sal_address_get_port_int((SalAddress*)dest)); -#endif sal_address_set_transport_name(route,transport); ret=ms_list_append(ret,route); } diff --git a/gtk/propertybox.c b/gtk/propertybox.c index a3bcc4145..c4dcd72ae 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -750,9 +750,11 @@ void linphone_gtk_proxy_cancel(GtkButton *button){ } void linphone_gtk_proxy_ok(GtkButton *button){ + LinphoneCore *lc=linphone_gtk_get_core(); GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button)); LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config"); int index=gtk_combo_box_get_active(GTK_COMBO_BOX(linphone_gtk_get_widget(w,"transport"))); + LinphoneTransportType tport=(LinphoneTransportType)index; gboolean was_editing=TRUE; if (!cfg){ @@ -765,7 +767,6 @@ void linphone_gtk_proxy_ok(GtkButton *button){ gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"proxy"))))==0){ if (index!=-1){ /*make sure transport was added to proxy address*/ - LinphoneTransportType tport=(LinphoneTransportType)index; LinphoneAddress *laddr=linphone_address_new(linphone_proxy_config_get_addr(cfg)); if (laddr){ if (linphone_address_get_transport(laddr)!=tport){ @@ -792,6 +793,17 @@ void linphone_gtk_proxy_ok(GtkButton *button){ linphone_proxy_config_enable_register(cfg, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")))); + + /* check if tls was asked but is not enabled in transport configuration*/ + if (tport==LinphoneTransportTls){ + LCSipTransports tports; + linphone_core_get_sip_transports(lc,&tports); + if (tports.tls_port==LC_SIP_TRANSPORT_DISABLED){ + tports.tls_port=LC_SIP_TRANSPORT_RANDOM; + } + linphone_core_set_sip_transports(lc,&tports); + } + if (was_editing){ if (linphone_proxy_config_done(cfg)==-1) return; From 7ee0e18910b91dabfab8a6fe1050b41374dffa52 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 1 Dec 2013 22:14:14 +0100 Subject: [PATCH 38/38] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 75514ad53..68d27760a 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 75514ad53cdda45632d35a474a2810e78b19997e +Subproject commit 68d27760a3d84df7818de0015f5bc01d31bf06af