]> sjero.net Git - linphone/commitdiff
Merge remote-tracking branch 'private/dev_videoios'
authorJehan Monnier <jehan.monnier@linphone.org>
Mon, 14 Nov 2011 10:10:24 +0000 (11:10 +0100)
committerJehan Monnier <jehan.monnier@linphone.org>
Mon, 14 Nov 2011 10:10:24 +0000 (11:10 +0100)
Conflicts:
mediastreamer2

34 files changed:
.gitmodules
Makefile.am
README.macos
README.mingw
build/android/Android.mk
configure.ac
console/commands.c
console/linphonec.c
coreapi/callbacks.c
coreapi/conference.c
coreapi/friend.c
coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/linphonecore_jni.cc
coreapi/lpconfig.c
coreapi/offeranswer.c
coreapi/private.h
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2_sdp.c
gtk/incall_view.c
gtk/linphone.h
gtk/main.c
gtk/main.ui
gtk/parameters.ui
gtk/propertybox.c
java/common/org/linphone/core/LinphoneCall.java
java/common/org/linphone/core/LinphoneCallParams.java
java/common/org/linphone/core/LinphoneCore.java
linphone-deps.filelist
mediastreamer2
oRTP
po/fr.po

index b3e1551c1da7ceed757f5e76bd9f5c815db9e108..0655d8e56ae99aa4cff04291206d981dad996eb7 100644 (file)
@@ -3,4 +3,4 @@
        url = git://git.linphone.org/ortp.git
 [submodule "mediastreamer2"]
        path = mediastreamer2
-       url = gitosis@git.linphone.org:mediastreamer2-private.git
+       url = git://git.linphone.org/mediastreamer2.git
index 036637737e91f1dcc3e8b468f971878ea8fec2dc..a1cd5594e364052b7282facd35f54e048c4b6dce 100644 (file)
@@ -85,6 +85,10 @@ rpm:
 
 #a zip containing win32 binaries, suitable to generate an installer
 
+if BUILD_ZRTP
+WINBINDIST_FILES+=./bin/libzrtpcpp.dll ./bin/msys-1.0.dll ./bin/msys-crypto-1.0.0.dll
+endif
+
 other-cherrypick:
        cd $(GTK_PREFIX) && \
        for file in $(WINBINDIST_FILES) ; do \
@@ -98,7 +102,7 @@ other-cherrypick:
                /mingw/bin/libstdc++-6.dll \
                /mingw/bin/libintl-8.dll \
                /mingw/bin/libiconv-2.dll \
-               /mingw/bin/libpthread-2.dll \
+               /mingw/bin/pthreadGC2.dll \
                $(INSTALLDIR_WITH_PREFIX)/bin/.
 
 
@@ -192,7 +196,7 @@ bundle: $(LIBICONV_HACK)
        make install DESTDIR=$(INSTALLDIR)
        LINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
        LIBLINPHONE_INSTALL_PREFIX=$(INSTALLDIR_WITH_PREFIX) \
-       ige-mac-bundler $(PACKAGE_BUNDLE_FILE)
+       gtk-mac-bundler $(PACKAGE_BUNDLE_FILE)
        printf "[Pango]\nModuleFiles=./etc/pango/pango.modules\n" \
        > $(BUNDLEDIR)/Contents/Resources/etc/pango/pangorc 
        cp -f $(LIBICONV_HACK) $(BUNDLEDIR)/Contents/Resources/lib/.
index e0878ee4e6bc0a6c37e9c4c9ebad45f93da1c29f..98b5b9fb60adf78a30ae815e577d859bf7b38878 100644 (file)
@@ -30,7 +30,7 @@ Compile:
  $ sudo make install
 
 When this version will be integrated into macports, only this will be necessary:
- $ port install sdl-devel
+ $ port install libsdl-devel
 
 - Install gtk. It is recommended to use the quartz backend for better integration.
  $ port install cairo +quartz +no_x11
@@ -53,11 +53,10 @@ Install to /opt/local
 
 Done.
 
-If you want to generate a portable bundle, then install ige-mac-bundler.
-The macport package of ige-mac-bundler doesn't work at all.
+If you want to generate a portable bundle, then install gtk-mac-bundler.
 Use git:
- $ git clone https://github.com/jralls/ige-mac-bundler.git
- $ cd ige-mac-bundler && make install
+ $ git clone https://github.com/jralls/gtk-mac-bundler.git 
+ $ cd gtk-mac-bundler && make install
  $ export PATH=$PATH:~/.local/bin
 
 Then run, inside linphone source tree:
index 5fa56c8445a15a6628dbe458bf4aff55f0612070..0c84e250ecb3eeac687c7da454e4da1546c36400 100644 (file)
@@ -14,6 +14,7 @@ In mingw shell, run
 mingw-get install msys-zip
 mingw-get install msys-unzip
 mingw-get install msys-wget
+mingw-get install msys-libopenssl
 
 mkdir -p /opt/perl/bin
 cp /bin/perl /opt/perl/bin/.
@@ -51,7 +52,7 @@ rm /lib/libgcc.a /lib/libmingw32.a /lib/libmingwex.a
 rm /lib/libintl.dll.a
 rm /lib/libintl.la
 rm /lib/libintl.a
-rm /include/intl.h
+rm /include/libintl.h
 
 * Download and install Inno Setup Compiler (required only if you run 'make setup.exe'). Add it to your windows Path environment variable.
 
index a7b9e024b3f515640f1a01d37169f51b47824e46..096f944641c211af8261355ea23ded7b38b1aacf 100755 (executable)
@@ -73,6 +73,7 @@ ifeq ($(BUILD_X264),1)
 LOCAL_CFLAGS += -DHAVE_X264
 endif
 endif
+
 LOCAL_C_INCLUDES += \
        $(LOCAL_PATH) \
        $(LOCAL_PATH)/include \
@@ -102,6 +103,11 @@ LOCAL_STATIC_LIBRARIES += \
        libopencoreamr 
 endif
 
+ifeq ($(BUILD_SILK),1)
+LOCAL_CFLAGS += -DHAVE_SILK
+LOCAL_STATIC_LIBRARIES += libmssilk
+endif
+
 ifeq ($(LINPHONE_VIDEO),1)
 LOCAL_LDLIBS    += -lGLESv2
 LOCAL_STATIC_LIBRARIES += libvpx
index f99e1dab49d741776281e6776c348135a8f5ba46..568f46b73d1c6e4e705b9c172ff072081e42d977 100644 (file)
@@ -1,6 +1,6 @@
 dnl Process this file with autoconf to produce a configure script.
 
-AC_INIT([linphone],[3.4.99.2],[linphone-developers@nongnu.org])
+AC_INIT([linphone],[3.4.99.4],[linphone-developers@nongnu.org])
 AC_CANONICAL_SYSTEM
 AC_CONFIG_SRCDIR([coreapi/linphonecore.c])
 
@@ -372,13 +372,14 @@ AC_ARG_ENABLE(alsa,
         *) AC_MSG_ERROR(bad value ${enableval} for --enable-alsa) ;;
       esac],[alsa=true])
 
-AC_ARG_ENABLE(artsc,
-      [  --enable-artsc    Turn on artsc (kde) sound input/output (auto) ],
+AC_ARG_ENABLE(zrtp,
+      [  --enable-zrtp    Turn on zrtp support - UNFINISHED],
       [case "${enableval}" in
-        yes) artsc=true ;;
-        no)  artsc=false ;;
-        *) AC_MSG_ERROR(bad value ${enableval} for --enable-artsc) ;;
-      esac],[artsc=false])
+        yes) zrtp=true ;;
+        no)  zrtp=false ;;
+        *) AC_MSG_ERROR(bad value ${enableval} for --enable-zrtp) ;;
+      esac],[zrtp=false])
+
 
 AC_ARG_ENABLE(portaudio,
       [  --enable-portaudio    Turn on portaudio native support compiling],
@@ -395,6 +396,7 @@ AM_CONDITIONAL(ARMBUILD, test x$use_arm_toolchain = xyes)
 dnl compilation of gtk user interface
 AM_CONDITIONAL(BUILD_GTK_UI, [test x$gtk_ui = xtrue ] )
 AM_CONDITIONAL(BUILD_WIN32, test x$mingw_found = xyes )
+AM_CONDITIONAL(BUILD_ZRTP, test x$zrtp = xtrue)
 
 dnl check getenv
 AH_TEMPLATE([HAVE_GETENV])
index 84639ada82f874d3da82ea41a1d1dcefdeb86fb1..e40dda66c35bc20fd690627a89071ac18052d983 100644 (file)
@@ -103,6 +103,7 @@ static int lpc_cmd_states(LinphoneCore *lc, char *args);
 static int lpc_cmd_identify(LinphoneCore *lc, char *args);
 static int lpc_cmd_ringback(LinphoneCore *lc, char *args);
 static int lpc_cmd_conference(LinphoneCore *lc, char *args);
+static int lpc_cmd_zrtp_verified(LinphoneCore *lc, char *args);
 
 /* Command handler helpers */
 static void linphonec_proxy_add(LinphoneCore *lc);
@@ -348,6 +349,9 @@ static LPC_COMMAND advanced_commands[] = {
        { "redirect", lpc_cmd_redirect, "Redirect an incoming call",
                "'redirect <redirect-uri>'\t: Redirect all pending incoming calls to the <redirect-uri>\n"
        },
+       { "zrtp-set-verified", lpc_cmd_zrtp_verified,"Set ZRTP SAS verified.",
+               "'Set ZRTP SAS verified'\n"
+       },
        {       NULL,NULL,NULL,NULL}
 };
 
@@ -2552,6 +2556,14 @@ static int lpc_cmd_ringback(LinphoneCore *lc, char *args){
        return 1;
 }
 
+static int lpc_cmd_zrtp_verified(LinphoneCore *lc, char *args){
+       LinphoneCall *call=linphone_core_get_current_call(lc);
+       if (linphone_call_params_get_media_encryption(linphone_call_get_current_params(call))==LinphoneMediaEncryptionZRTP){
+               linphone_call_set_authentication_token_verified(call,TRUE);
+       }
+       return 1;
+}
+
 /***************************************************************************
  *
  *  Command table management funx
index 6bb624f1ca1f883226ac729fd576e567ab7abfff..e0321089b4dd9abadb1aa422fa85987c7c20af13 100644 (file)
@@ -160,6 +160,7 @@ LPC_AUTH_STACK auth_stack;
 static int trace_level = 0;
 static char *logfile_name = NULL;
 static char configfile_name[PATH_MAX];
+static char zrtpsecrets[PATH_MAX];
 static const char *factory_configfile_name=NULL;
 static char *sip_addr_to_call = NULL; /* for autocall */
 static int window_id = 0; /* 0=standalone window, or window id for embedding video */
@@ -667,6 +668,8 @@ linphonec_init(int argc, char **argv)
 #ifndef _WIN32
        snprintf(configfile_name, PATH_MAX, "%s/.linphonerc",
                        getenv("HOME"));
+       snprintf(zrtpsecrets, PATH_MAX, "%s/.linphone-zidcache",
+                       getenv("HOME"));
 #elif defined(_WIN32_WCE)
        strncpy(configfile_name,PACKAGE_DIR "\\linphonerc",PATH_MAX);
        mylogfile=fopen(PACKAGE_DIR "\\" "linphonec.log","w");
@@ -674,6 +677,8 @@ linphonec_init(int argc, char **argv)
 #else
        snprintf(configfile_name, PATH_MAX, "%s/Linphone/linphonerc",
                        getenv("APPDATA"));
+       snprintf(zrtpsecrets, PATH_MAX, "%s/Linphone/linphone-zidcache",
+                       getenv("APPDATA"));
 #endif
        /* Handle configuration filename changes */
        switch (handle_configfile_migration())
@@ -728,6 +733,7 @@ linphonec_init(int argc, char **argv)
         * Initialize linphone core
         */
        linphonec=linphone_core_new (&linphonec_vtable, configfile_name, factory_configfile_name, NULL);
+       linphone_core_set_zrtp_secrets_file(linphonec,zrtpsecrets);
        linphone_core_enable_video(linphonec,vcap_enabled,display_enabled);
        if (display_enabled && window_id != 0) 
        {
index ed561c216bf9ccdef34486e686860e8380454335..7b79a78d6dde39bc343607cad74905829ae3aa06 100644 (file)
@@ -108,6 +108,21 @@ static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, c
 }
 #endif
 
+static bool_t already_a_call_with_remote_address(const LinphoneCore *lc, const LinphoneAddress *remote) {
+       ms_warning(" searching for already_a_call_with_remote_address.");
+
+       MSList *elem;
+       for(elem=lc->calls;elem!=NULL;elem=elem->next){
+               const LinphoneCall *call=(LinphoneCall*)elem->data;
+               const LinphoneAddress *cRemote=linphone_call_get_remote_address(call);
+               if (linphone_address_weak_equal(cRemote,remote)) {
+                       ms_warning("already_a_call_with_remote_address found.");
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
 static bool_t already_a_call_pending(LinphoneCore *lc){
        MSList *elem;
        for(elem=lc->calls;elem!=NULL;elem=elem->next){
@@ -133,6 +148,7 @@ static void call_received(SalOp *h){
        LinphoneAddress *from_addr, *to_addr;
        SalMediaDescription *md;
        bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
+       bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE);
        const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
        
        /* first check if we can answer successfully to this invite */
@@ -161,7 +177,7 @@ static void call_received(SalOp *h){
        from_addr=linphone_address_new(from);
        to_addr=linphone_address_new(to);
 
-       if (already_a_call_pending(lc)){
+       if ((already_a_call_with_remote_address(lc,from_addr) && prevent_colliding_calls) || already_a_call_pending(lc)){
                ms_warning("Receiving another call while one is ringing or initiated, refusing this one with busy message.");
                sal_call_decline(h,SalReasonBusy,NULL);
                sal_op_release(h);
@@ -395,6 +411,9 @@ static void call_updating(SalOp *op){
        LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
        LinphoneCallState prevstate=LinphoneCallIdle;
        SalMediaDescription *md;
+       SalMediaDescription *old_md=call->resultdesc;
+
+       sal_media_description_ref(old_md);
        
        md=sal_call_get_final_media_description(op);
 
@@ -412,12 +431,10 @@ static void call_updating(SalOp *op){
                                if(lc->vtable.display_status)
                                        lc->vtable.display_status(lc,_("We are being paused..."));
                                linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
-                       }else if (!sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && sal_media_description_has_dir(md,SalStreamSendRecv)){
+                       }else if (!sal_media_description_has_dir(old_md,SalStreamSendRecv) && sal_media_description_has_dir(md,SalStreamSendRecv)){
                                if(lc->vtable.display_status)
                                        lc->vtable.display_status(lc,_("We have been resumed..."));
                                linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
-                               if (!call->current_params.in_conference)
-                                       lc->current_call=call;
                        }else{
                                prevstate=call->state;
                                if(lc->vtable.display_status)
@@ -430,6 +447,7 @@ static void call_updating(SalOp *op){
                        linphone_call_set_state (call,prevstate,"Connected (streams running)");
                }
        }
+       sal_media_description_unref(old_md);
 }
 
 static void call_terminated(SalOp *op, const char *from){
@@ -515,6 +533,21 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
                                        lc->vtable.display_status(lc,msg600);
                        break;
                        case SalReasonMedia:
+                       //media_encryption_mandatory
+                               if (call->params.media_encryption == LinphoneMediaEncryptionSRTP && 
+                                       !linphone_core_is_media_encryption_mandatory(lc)) {
+                                       int i;
+                                       ms_message("Outgoing call failed with SRTP (SAVP) enabled - retrying with AVP");
+                                       linphone_call_stop_media_streams(call);
+                                       /* clear SRTP local params */
+                                       call->params.media_encryption = LinphoneMediaEncryptionNone;
+                                       for(i=0; i<call->localdesc->nstreams; i++) {
+                                               call->localdesc->streams[i].proto = SalProtoRtpAvp;
+                                               memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
+                                       }
+                                       linphone_core_start_invite(lc, call, NULL);
+                                       return;
+                               }
                                msg=_("No common codecs");
                                if (lc->vtable.display_status)
                                        lc->vtable.display_status(lc,msg);
index 767eaf07dae3fff157048a5e904c7ffa65d2df1f..5992024ae23da5eb4f190a9b37518ab0036ddc1f 100644 (file)
@@ -140,6 +140,7 @@ int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
        conference_check_init(&lc->conf_ctx);
        call->params.in_conference=TRUE;
        call->params.has_video=FALSE;
+       call->params.media_encryption=LinphoneMediaEncryptionNone;
        params=call->params;
        if (call->state==LinphoneCallPaused)
                linphone_core_resume_call(lc,call);
@@ -189,6 +190,9 @@ int linphone_core_leave_conference(LinphoneCore *lc){
 
 
 int linphone_core_enter_conference(LinphoneCore *lc){
+       if (linphone_core_sound_resources_locked(lc)) {
+               return -1;
+       }
        LinphoneConference *conf=&lc->conf_ctx;
        if (conf->local_participant==NULL) add_local_endpoint(conf,lc);
        return 0;
index 853902b45f23dfbdb9cf085b550c05691bebe26a..05a1baeec3a7ed26013cc44a758b614042dc138f 100644 (file)
@@ -444,6 +444,10 @@ LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, cons
        }
        username=linphone_address_get_username(puri);
        domain=linphone_address_get_domain(puri);
+       if (domain==NULL) {
+               linphone_address_destroy(puri);
+               return NULL;
+       }
        for(elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){
                lf=(LinphoneFriend*)elem->data;
                const char *it_username=linphone_address_get_username(lf->uri);
index dee7a21cc79a7393221dafb1fc99880f5a31bf51..0310ec63340a66adf46346ff269bb0bbfb622133 100644 (file)
@@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "lpconfig.h"
 #include "private.h"
 #include <ortp/event.h>
+#include <ortp/b64.h>
 
 
 #include "mediastreamer2/mediastream.h"
@@ -41,6 +42,27 @@ static MSWebCam *get_nowebcam_device(){
 }
 #endif
 
+static bool_t generate_b64_crypto_key(int key_length, char* key_out) {
+       int b64_size;
+       uint8_t* tmp = (uint8_t*) malloc(key_length);                   
+       if (ortp_crypto_get_random(tmp, key_length)!=0) {
+               ms_error("Failed to generate random key");
+               free(tmp);
+               return FALSE;
+       }
+       
+       b64_size = b64_encode((const char*)tmp, key_length, NULL, 0);
+       if (b64_size == 0) {
+               ms_error("Failed to b64 encode key");
+               free(tmp);
+               return FALSE;
+       }
+       key_out[b64_size] = '\0';
+       b64_encode((const char*)tmp, key_length, key_out, 40);
+       free(tmp);
+       return TRUE;
+}
+
 LinphoneCore *linphone_call_get_core(const LinphoneCall *call){
        return call->core;
 }
@@ -64,7 +86,8 @@ const char* linphone_call_get_authentication_token(LinphoneCall *call){
 bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call){
        return call->auth_token_verified;
 }
-bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) {
+
+static bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) {
        // Check ZRTP encryption in audiostream
        if (!call->audiostream_encrypted) {
                return FALSE;
@@ -82,14 +105,17 @@ bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call) {
 }
 
 void propagate_encryption_changed(LinphoneCall *call){
-       if (call->core->vtable.call_encryption_changed == NULL) return;
-
+       LinphoneCore *lc=call->core;
        if (!linphone_call_are_all_streams_encrypted(call)) {
                ms_message("Some streams are not encrypted");
-               call->core->vtable.call_encryption_changed(call->core, call, FALSE, call->auth_token);
+               call->current_params.media_encryption=LinphoneMediaEncryptionNone;
+               if (lc->vtable.call_encryption_changed)
+                       lc->vtable.call_encryption_changed(call->core, call, FALSE, call->auth_token);
        } else {
                ms_message("All streams are encrypted");
-               call->core->vtable.call_encryption_changed(call->core, call, TRUE, call->auth_token);
+               call->current_params.media_encryption=LinphoneMediaEncryptionZRTP;
+               if (lc->vtable.call_encryption_changed)
+                       lc->vtable.call_encryption_changed(call->core, call, TRUE, call->auth_token);
        }
 }
 
@@ -109,7 +135,7 @@ static void linphone_call_audiostream_encryption_changed(void *data, bool_t encr
 
        LinphoneCall *call = (LinphoneCall *)data;
        call->audiostream_encrypted=encrypted;
-
+       
        if (encrypted && call->core->vtable.display_status != NULL) {
                snprintf(status,sizeof(status)-1,_("Authentication token is %s"),call->auth_token);
                 call->core->vtable.display_status(call->core, status);
@@ -143,6 +169,21 @@ static void linphone_call_audiostream_auth_token_ready(void *data, const char* a
        ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified");
 }
 
+void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified){
+       if (call->audiostream==NULL){
+               ms_error("linphone_call_set_authentication_token_verified(): No audio stream");
+       }
+       if (call->audiostream->ortpZrtpContext==NULL){
+               ms_error("linphone_call_set_authentication_token_verified(): No zrtp context.");
+       }
+       if (!call->auth_token_verified && verified){
+               ortp_zrtp_sas_verified(call->audiostream->ortpZrtpContext);
+       }else if (call->auth_token_verified && !verified){
+               ortp_zrtp_sas_reset_verified(call->audiostream->ortpZrtpContext);
+       }
+       call->auth_token_verified=verified;
+       propagate_encryption_changed(call);
+}
 
 static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){
        MSList *l=NULL;
@@ -165,6 +206,7 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw
 static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, LinphoneCall *call, unsigned int session_id, unsigned int session_ver){
        MSList *l;
        PayloadType *pt;
+       int i;
        const char *me=linphone_core_get_identity(lc);
        LinphoneAddress *addr=linphone_address_new(me);
        const char *username=linphone_address_get_username (addr);
@@ -180,7 +222,8 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
        /*set audio capabilities */
        strncpy(md->streams[0].addr,call->localip,sizeof(md->streams[0].addr));
        md->streams[0].port=call->audio_port;
-       md->streams[0].proto=SalProtoRtpAvp;
+       md->streams[0].proto=(call->params.media_encryption == LinphoneMediaEncryptionSRTP) ? 
+               SalProtoRtpSavp : SalProtoRtpAvp;
        md->streams[0].type=SalAudio;
        md->streams[0].ptime=lc->net_conf.down_ptime;
        l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw);
@@ -192,11 +235,26 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
        if (call->params.has_video){
                md->nstreams++;
                md->streams[1].port=call->video_port;
-               md->streams[1].proto=SalProtoRtpAvp;
+               md->streams[1].proto=md->streams[0].proto;
                md->streams[1].type=SalVideo;
                l=make_codec_list(lc,lc->codecs_conf.video_codecs,0);
                md->streams[1].payloads=l;
        }
+       
+       for(i=0; i<md->nstreams; i++) {
+               if (md->streams[i].proto == SalProtoRtpSavp) {
+                       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))
+                               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))
+                               md->streams[i].crypto[1].algo = 0;
+                       md->streams[i].crypto[2].algo = 0;
+               }
+       }
+       
        linphone_address_destroy(addr);
        return md;
 }
@@ -286,7 +344,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
                linphone_core_run_stun_tests(call->core,call);
        discover_mtu(lc,linphone_address_get_domain (to));
        if (params->referer){
-               sal_call_set_referer (call->op,params->referer->op);
+               sal_call_set_referer(call->op,params->referer->op);
        }
        return call;
 }
@@ -314,7 +372,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
        linphone_address_clean(from);
        linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
        linphone_call_init_common(call, from, to);
-       call->params.has_video=linphone_core_video_enabled(lc);
+       linphone_core_init_default_params(lc, &call->params);
        call->localdesc=create_local_media_description (lc,call);
        call->camera_active=call->params.has_video;
        if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun)
@@ -408,7 +466,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
                if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){
                        if (cstate!=LinphoneCallReleased){
                                ms_warning("Spurious call state change from %s to %s, ignored.",linphone_call_state_to_string(call->state),
-                          linphone_call_state_to_string(cstate));
+                                  linphone_call_state_to_string(cstate));
                                return;
                        }
                }
@@ -421,13 +479,14 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
                }
                if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
              if (call->reason==LinphoneReasonDeclined){
-                 call->log->status=LinphoneCallDeclined;
-             }
-            linphone_call_set_terminated (call);
+                               call->log->status=LinphoneCallDeclined;
+                       }
+                       linphone_call_set_terminated (call);
+               }
+               if (cstate == LinphoneCallConnected) {
+                       call->log->status=LinphoneCallSuccess;
+                       call->media_start_time=time(NULL);
                }
-        if (cstate == LinphoneCallConnected) {
-            call->log->status=LinphoneCallSuccess;
-        }
 
                if (lc->vtable.call_state_changed)
                        lc->vtable.call_state_changed(lc,call,cstate,message);
@@ -679,6 +738,15 @@ bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
        return cp->has_video;
 }
 
+enum LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp) {
+       return cp->media_encryption;
+}
+
+void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, enum LinphoneMediaEncryption e) {
+       cp->media_encryption = e;
+}
+
+
 /**
  * Enable sending of real early media (during outgoing calls).
 **/
@@ -989,7 +1057,12 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
        LinphoneCore *lc=call->core;
        int jitt_comp=lc->rtp_conf.audio_jitt_comp;
        int used_pt=-1;
+       /* look for savp stream first */
        const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+                                               SalProtoRtpSavp,SalAudio);
+       /* no savp audio stream, use avp */
+       if (!stream)
+               stream=sal_media_description_find_stream(call->resultdesc,
                                                SalProtoRtpAvp,SalAudio);
 
        if (stream && stream->dir!=SalStreamInactive && stream->port!=0){
@@ -1070,6 +1143,17 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna
                                /*transform the graph to connect it to the conference filter */
                                linphone_call_add_to_conf(call);
                        }
+                       
+                       if (stream->proto == SalProtoRtpSavp) {
+                               const SalStreamDescription *local_st_desc=sal_media_description_find_stream(call->localdesc,
+                                               SalProtoRtpSavp,SalAudio);
+                                               
+                               audio_stream_enable_strp(
+                                       call->audiostream, 
+                                       stream->crypto[0].algo,
+                                       local_st_desc->crypto[0].master_key,
+                                       stream->crypto[0].master_key);                          
+                       }
                }else ms_warning("No audio stream accepted ?");
        }
 }
@@ -1078,8 +1162,14 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
 #ifdef VIDEO_ENABLED
        LinphoneCore *lc=call->core;
        int used_pt=-1;
+       /* look for savp stream first */
        const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
-                                                       SalProtoRtpAvp,SalVideo);
+                                               SalProtoRtpSavp,SalVideo);
+       /* no savp audio stream, use avp */
+       if (!vstream)
+               vstream=sal_media_description_find_stream(call->resultdesc,
+                                               SalProtoRtpAvp,SalVideo);
+                                               
        /* shutdown preview */
        if (lc->previewstream!=NULL) {
                video_preview_stop(lc->previewstream);
@@ -1136,6 +1226,18 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
                                        used_pt, lc->rtp_conf.audio_jitt_comp, cam);
                                video_stream_set_rtcp_information(call->videostream, cname,LINPHONE_RTCP_SDES_TOOL);
                        }
+                       
+                       if (vstream->proto == SalProtoRtpSavp) {
+                               const SalStreamDescription *local_st_desc=sal_media_description_find_stream(call->localdesc,
+                                               SalProtoRtpSavp,SalVideo);
+                                               
+                               video_stream_enable_strp(
+                                       call->videostream, 
+                                       vstream->crypto[0].algo,
+                                       local_st_desc->crypto[0].master_key, 
+                                       vstream->crypto[0].master_key
+                                       );                              
+                       }
                }else ms_warning("No video stream accepted.");
        }else{
                ms_warning("No valid video stream defined.");
@@ -1159,7 +1261,6 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
                return;
        }
        call->current_params = call->params;
-       if (call->media_start_time==0) call->media_start_time=time(NULL);
        cname=linphone_address_as_string_uri_only(me);
 
 #if defined(VIDEO_ENABLED)
@@ -1177,8 +1278,11 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
        call->playing_ringbacktone=send_ringbacktone;
        call->up_bw=linphone_core_get_upload_bandwidth(lc);
 
-       if (ortp_zrtp_available()) {
+       if (call->params.media_encryption==LinphoneMediaEncryptionZRTP) {
                OrtpZrtpParams params;
+               /*will be set later when zrtp is activated*/
+               call->current_params.media_encryption=LinphoneMediaEncryptionNone;
+               
                params.zid=get_hexa_zrtp_identifier(lc);
                params.zid_file=lc->zrtp_secrets_cache;
                audio_stream_enable_zrtp(call->audiostream,&params);
index 49dad24ff7fbf35c37027c6eaa3cb61eaffbc616..2106e6c51873fbb5919b58b03f5504cc1f400f79 100644 (file)
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "private.h"
 
 #include <ortp/telephonyevents.h>
+#include <ortp/zrtp.h>
 #include "mediastreamer2/mediastream.h"
 #include "mediastreamer2/mseventqueue.h"
 #include "mediastreamer2/msvolume.h"
@@ -35,6 +36,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #endif
 #endif
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 /*#define UNSTANDART_GSM_11K 1*/
 
 #define ROOT_CA_FILE PACKAGE_DATA_DIR "/linphone/rootca.pem"
@@ -523,7 +528,7 @@ static void sip_config_read(LinphoneCore *lc)
 #else
        sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE));
 #endif
-
+       
        tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1);
        linphone_core_set_guess_hostname(lc,tmp);
 
@@ -554,6 +559,8 @@ static void sip_config_read(LinphoneCore *lc)
                        break;
                }
        }
+       /*this is to filter out unsupported encryption schemes*/
+       linphone_core_set_media_encryption(lc,linphone_core_get_media_encryption(lc));
 
        /*for tuning or test*/
        lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
@@ -4266,7 +4273,7 @@ LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc){
 
 LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc){
        LinphoneCallParams *p=ms_new0(LinphoneCallParams,1);
-       p->has_video=linphone_core_video_enabled(lc);
+       linphone_core_init_default_params(lc, p);
        return p;
 }
 
@@ -4317,7 +4324,9 @@ void linphone_core_stop_dtmf_stream(LinphoneCore* lc) {
 int linphone_core_get_max_calls(LinphoneCore *lc) {
        return lc->max_calls;
 }
-
+void linphone_core_set_max_calls(LinphoneCore *lc, int max) {
+       lc->max_calls=max;
+}
 
 typedef struct Hook{
        LinphoneCoreIterateHook fun;
@@ -4369,7 +4378,6 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){
        lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL;
 }
 
-//                             if (stringUri.equals(call.getRemoteAddress().asStringUriOnly())) {
 const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const char *uri) {
        if (uri == NULL) return NULL;
        MSList *calls=lc->calls;
@@ -4387,3 +4395,99 @@ const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const cha
        }
        return NULL;
 }
+
+
+/**
+ * Check if a call will need the sound resources.
+ *
+ * @ingroup call_control
+ * @param lc The LinphoneCore
+**/
+bool_t linphone_core_sound_resources_locked(LinphoneCore *lc){
+       MSList *calls=lc->calls;
+       while(calls) {
+               LinphoneCall *c=(LinphoneCall*)calls->data;
+               calls=calls->next;
+               switch (c->state) {
+                       case LinphoneCallOutgoingInit:
+                       case LinphoneCallOutgoingProgress:
+                       case LinphoneCallOutgoingRinging:
+                       case LinphoneCallOutgoingEarlyMedia:
+                       case LinphoneCallConnected:
+                       case LinphoneCallRefered:
+                       case LinphoneCallIncomingEarlyMedia:
+                       case LinphoneCallUpdated:
+                               return TRUE;
+                       default:
+                               break;
+               }
+       }
+       return FALSE;
+}
+
+void linphone_core_set_srtp_enabled(LinphoneCore *lc, bool_t enabled) {
+       lp_config_set_int(lc->config,"sip","srtp",(int)enabled);
+}
+
+/**
+ * Returns whether a media encryption scheme is supported by the LinphoneCore engine
+**/
+bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc){
+       switch(menc){
+               case LinphoneMediaEncryptionSRTP:
+                       return ortp_srtp_supported();
+               case LinphoneMediaEncryptionZRTP:
+                       return ortp_zrtp_available();
+               case LinphoneMediaEncryptionNone:
+                       return TRUE;
+       }
+       return FALSE;
+}
+
+int linphone_core_set_media_encryption(LinphoneCore *lc, enum LinphoneMediaEncryption menc) {
+       const char *type="none";
+       int ret=0;
+       if (menc == LinphoneMediaEncryptionSRTP){
+               if (!ortp_srtp_supported()){
+                       ms_warning("SRTP not supported by library.");
+                       type="none";
+                       ret=-1;
+               }else type="srtp";
+       }else if (menc == LinphoneMediaEncryptionZRTP){
+               if (!ortp_zrtp_available()){
+                       ms_warning("ZRTP not supported by library.");
+                       type="none";
+                       ret=-1;
+               }else type="zrtp";
+       }
+       lp_config_set_string(lc->config,"sip","media_encryption",type);
+       return ret;
+}
+
+LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc) {
+       const char* menc = lp_config_get_string(lc->config, "sip", "media_encryption", NULL);
+       
+       if (menc == NULL)
+               return LinphoneMediaEncryptionNone;
+       else if (strcmp(menc, "srtp")==0)
+               return LinphoneMediaEncryptionSRTP;
+       else if (strcmp(menc, "zrtp")==0)
+               return LinphoneMediaEncryptionZRTP;
+       else
+               return LinphoneMediaEncryptionNone;
+}
+
+bool_t linphone_core_is_media_encryption_mandatory(LinphoneCore *lc) {
+       return (bool_t)lp_config_get_int(lc->config, "sip", "media_encryption_mandatory", 0);
+}
+
+void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m) {
+       lp_config_set_int(lc->config, "sip", "media_encryption_mandatory", (int)m);
+}
+
+void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *params) {
+       params->has_video=linphone_core_video_enabled(lc);
+       params->media_encryption=linphone_core_get_media_encryption(lc);        
+       params->in_conference=FALSE;
+}
+
index d99ddb7732ad2a90359cbddd16b646608bde1a02..01353a3cae1dae963fe05c11587f38e8270b9c9f 100644 (file)
@@ -156,7 +156,13 @@ typedef struct _LinphoneCallLog{
        struct _LinphoneCore *lc;
 } LinphoneCallLog;
 
+enum LinphoneMediaEncryption {
+       LinphoneMediaEncryptionNone,
+       LinphoneMediaEncryptionSRTP,
+       LinphoneMediaEncryptionZRTP
+};
 
+typedef enum LinphoneMediaEncryption LinphoneMediaEncryption;
 
 /*public: */
 void linphone_call_log_set_user_pointer(LinphoneCallLog *cl, void *up);
@@ -179,6 +185,8 @@ typedef struct _LinphoneCallParams LinphoneCallParams;
 LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp);
 void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled);
 bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
+LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp);
+void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption e);
 void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
 bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
 bool_t linphone_call_params_local_conference_mode(const LinphoneCallParams *cp);
@@ -259,6 +267,10 @@ float linphone_call_get_play_volume(LinphoneCall *call);
 float linphone_call_get_record_volume(LinphoneCall *call);
 float linphone_call_get_current_quality(LinphoneCall *call);
 float linphone_call_get_average_quality(LinphoneCall *call);
+const char* linphone_call_get_authentication_token(LinphoneCall *call);
+bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call);
+void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified);
+void linphone_call_send_vfu_request(LinphoneCall *call);
 void *linphone_call_get_user_pointer(LinphoneCall *call);
 void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
 /**
@@ -1008,15 +1020,9 @@ LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc);
  */
 void linphone_core_refresh_registers(LinphoneCore* lc);
 
-
-void linphone_call_send_vfu_request(LinphoneCall *call);
-
 /* Path to the file storing secrets cache */
 void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file);
 
-bool_t linphone_call_are_all_streams_encrypted(LinphoneCall *call);
-const char* linphone_call_get_authentication_token(LinphoneCall *call);
-bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call);
 
 const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const char *uri);
 
@@ -1032,6 +1038,29 @@ int linphone_core_terminate_conference(LinphoneCore *lc);
 int linphone_core_get_conference_size(LinphoneCore *lc);
 
 int linphone_core_get_max_calls(LinphoneCore *lc);
+void linphone_core_set_max_calls(LinphoneCore *lc, int max);
+
+bool_t linphone_core_sound_resources_locked(LinphoneCore *lc);
+
+bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc);
+
+/**
+ * Choose media encryption policy to be used for RTP packets
+ */
+int linphone_core_set_media_encryption(LinphoneCore *lc, enum LinphoneMediaEncryption menc);
+LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc);
+
+bool_t linphone_core_is_media_encryption_mandatory(LinphoneCore *lc);
+/**
+ * Defines Linphone behaviour when encryption parameters negociation fails on outoing call.
+ * If set to TRUE call will fail; if set to FALSE will resend an INVITE with encryption disabled
+ */
+void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m);
+
+/**
+ * Init call params using LinphoneCore's current configuration
+ */
+void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *params);
 
 #ifdef __cplusplus
 }
index 8713e86d20a04c8a8745def708b126b900d09c37..fb62302afec622a5028670e570982fbd9bc4bd13 100644 (file)
@@ -36,6 +36,9 @@ extern "C" void libmsx264_init();
 #ifdef HAVE_AMR
 extern "C" void libmsamr_init();
 #endif
+#ifdef HAVE_SILK
+extern "C" void libmssilk_init();
+#endif
 #endif /*ANDROID*/
 
 static JavaVM *jvm=0;
@@ -405,6 +408,9 @@ extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv*
 #endif
 #ifdef HAVE_AMR
        libmsamr_init();
+#endif
+#ifdef HAVE_SILK
+       libmssilk_init();
 #endif
        jlong nativePtr = (jlong)linphone_core_new(     &ldata->vTable
                        ,userConfig
@@ -769,7 +775,82 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_startEchoCalibration(JNI
 
 }
 
+static enum LinphoneMediaEncryption media_encryption_string_to_enum(const char* menc) {
+       if (menc==NULL)
+               return LinphoneMediaEncryptionNone;
+       else if (strcasecmp(menc, "none")==0)
+               return LinphoneMediaEncryptionNone;
+       else if (strcasecmp(menc, "srtp")==0)
+               return LinphoneMediaEncryptionSRTP;
+       else if (strcasecmp(menc, "zrtp")==0)
+               return LinphoneMediaEncryptionZRTP;
+       else
+               return LinphoneMediaEncryptionNone;
+}
+
+static jstring media_encryption_enum_to_jstring(JNIEnv*  env, enum LinphoneMediaEncryption enc) {
+       switch (enc) {
+               case LinphoneMediaEncryptionSRTP:
+                       return env->NewStringUTF("srtp");
+               case LinphoneMediaEncryptionZRTP:
+                       return env->NewStringUTF("zrtp");
+               case LinphoneMediaEncryptionNone:
+                       return env->NewStringUTF("none");
+               default:
+                       return NULL;
+       }
+}
 
+extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getMediaEncryption(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       ) {
+       return media_encryption_enum_to_jstring(env,
+               linphone_core_get_media_encryption((LinphoneCore*)lc));
+}
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMediaEncryption(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       ,jstring jmenc) {
+       const char* menc = jmenc?env->GetStringUTFChars(jmenc, NULL):NULL;
+       
+       linphone_core_set_media_encryption((LinphoneCore*)lc,
+               media_encryption_string_to_enum(menc));
+
+       if (menc) env->ReleaseStringUTFChars(jmenc, menc);
+}
+
+extern "C" jstring Java_org_linphone_core_LinphoneCallParamsImpl_getMediaEncryption(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       ) {
+       return media_encryption_enum_to_jstring(env,
+               linphone_call_params_get_media_encryption((LinphoneCallParams*)lc));
+}
+extern "C" void Java_org_linphone_core_LinphoneCallParamsImpl_setMediaEncryption(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       ,jstring jmenc) {
+       const char* menc = jmenc?env->GetStringUTFChars(jmenc, NULL):NULL;
+       linphone_call_params_set_media_encryption((LinphoneCallParams*)lc,
+               media_encryption_string_to_enum(menc));
+       if (menc) env->ReleaseStringUTFChars(jmenc, menc);
+}
+
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_getMediaEncryptionMandatory(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       ) {
+       return linphone_core_is_media_encryption_mandatory((LinphoneCore*)lc);
+}
+
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMediaEncryptionMandatory(JNIEnv*  env
+                                                                                                                                                       ,jobject  thiz
+                                                                                                                                                       ,jlong lc
+                                                                                                                                                       , jboolean yesno
+                                                                                                                                                       ) {
+       linphone_core_set_media_encryption_mandatory((LinphoneCore*)lc, yesno);
+}
 
 //ProxyConfig
 
@@ -1496,8 +1577,9 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isAuthenticationToke
        LinphoneCall *call = (LinphoneCall *) ptr;
        return linphone_call_get_authentication_token_verified(call);
 }
-extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_areStreamsEncrypted(JNIEnv*  env,jobject thiz,jlong ptr) {
-       return linphone_call_are_all_streams_encrypted((LinphoneCall *) ptr);
+
+extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_soundResourcesLocked(JNIEnv* env,jobject thiz,jlong ptr){
+       return linphone_core_sound_resources_locked((LinphoneCore *) ptr);
 }
 
 // Needed by Galaxy S (can't switch to/from speaker while playing and still keep mic working)
@@ -1513,3 +1595,6 @@ extern "C" void Java_org_linphone_LinphoneManager_hackSpeakerState(JNIEnv*  env,
 extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getMaxCalls(JNIEnv *env,jobject thiz,jlong pCore) {
        return (jint) linphone_core_get_max_calls((LinphoneCore *) pCore);
 }
+extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMaxCalls(JNIEnv *env,jobject thiz,jlong pCore, jint max) {
+       linphone_core_set_max_calls((LinphoneCore *) pCore, (int) max);
+}
index 0de019e57fdb9fd9cc06c98137f7bbd5df5d8125..d12166ec49209b4a1265596a198c680aa8cd17d9 100644 (file)
@@ -22,7 +22,7 @@
  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-#define MAX_LEN 32768
+#define MAX_LEN 16384
 
 #include "linphonecore.h"
 
@@ -138,12 +138,13 @@ LpItem *lp_section_find_item(LpSection *sec, const char *name){
 }
 
 void lp_config_parse(LpConfig *lpconfig, FILE *file){
-       char tmp[MAX_LEN];
+       char tmp[MAX_LEN]= {'\0'};
        LpSection *cur=NULL;
 
        if (file==NULL) return;
 
        while(fgets(tmp,MAX_LEN,file)!=NULL){
+               tmp[sizeof(tmp) -1] = '\0';
                char *pos1,*pos2;
                pos1=strchr(tmp,'[');
                if (pos1!=NULL && is_first_char(tmp,pos1) ){
index 3e054508b1aa5a863287569b5ed9730957f49619..ab213a2391b591c3013603e26657145a6538d256 100644 (file)
@@ -128,6 +128,31 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
        return res;
 }
 
+static bool_t match_crypto_algo(const SalSrtpCryptoAlgo* local, const SalSrtpCryptoAlgo* remote, 
+       SalSrtpCryptoAlgo* result, bool_t use_local_key) {
+       int i,j;
+       for(i=0; i<SAL_CRYPTO_ALGO_MAX; i++) {
+               if (remote[i].algo == 0)
+                       break;
+                       
+               for(j=0; j<SAL_CRYPTO_ALGO_MAX; j++) {
+                       if (remote[i].algo == local[j].algo) {
+                               result->algo = remote[i].algo;
+                               if (use_local_key) {
+                                       strncpy(result->master_key, local[j].master_key, 41);
+                                       result->tag = local[j].tag;
+                               } else {
+                                       strncpy(result->master_key, remote[j].master_key, 41);
+                                       result->tag = remote[j].tag;
+                               }
+                               result->master_key[40] = '\0';
+                               return TRUE;
+                       }
+               }
+       }
+       return FALSE;
+}
+
 
 
 static SalStreamDir compute_dir_outgoing(SalStreamDir local, SalStreamDir answered){
@@ -174,7 +199,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
                                        SalStreamDescription *result){
        if (remote_answer->port!=0)
                result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
-       result->proto=local_offer->proto;
+       result->proto=remote_answer->proto;
        result->type=local_offer->type;
        result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
 
@@ -186,6 +211,12 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
        }else{
                result->port=0;
        }
+       if (result->proto == SalProtoRtpSavp) {
+               /* verify crypto algo */
+               memset(result->crypto, 0, sizeof(result->crypto));
+               if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], FALSE))
+                       result->port = 0;
+       }
 }
 
 
@@ -193,7 +224,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
                                        const SalStreamDescription *remote_offer,
                                        SalStreamDescription *result, bool_t one_matching_codec){
        result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
-       result->proto=local_cap->proto;
+       result->proto=remote_offer->proto;
        result->type=local_cap->type;
        result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
        if (result->payloads && !only_telephone_event(result->payloads)){
@@ -205,6 +236,13 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
        }else{
                result->port=0;
        }
+       if (result->proto == SalProtoRtpSavp) {
+               /* select crypto algo */
+               memset(result->crypto, 0, sizeof(result->crypto));
+               if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], TRUE))
+                       result->port = 0; 
+               
+       }
 }
 
 /**
@@ -215,6 +253,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
                                                                        const SalMediaDescription *remote_answer,
                                                        SalMediaDescription *result){
     int i,j;
+    
        const SalStreamDescription *ls,*rs;
     for(i=0,j=0;i<local_offer->nstreams;++i){
                ms_message("Processing for stream %i",i);
@@ -246,10 +285,18 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
     for(i=0;i<remote_offer->nstreams;++i){
                rs=&remote_offer->streams[i];
                ms_message("Processing for stream %i",i);
+               
                ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
+               ms_message("remote proto: %s => %p", (rs->proto == SalProtoRtpAvp)?"AVP":"SAVP", ls);
+               /* if matching failed, and remote proposes Avp only, ask for local Savp streams */ 
+               if (!ls && rs->proto == SalProtoRtpAvp) {
+                       ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,SalProtoRtpSavp,rs->type);
+                       ms_message("retry with AVP => %p", ls);
+               }
                if (ls){
                initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
-               } else {
+               }
+               else {
                        /* create an inactive stream for the answer, as there where no matching stream a local capability */
                        result->streams[i].dir=SalStreamInactive;
                        result->streams[i].port=0;
index f90f27bf21ae628c893ff5eb212e31dda71009c5..657cd47fd43e2ecec00736a728cc3c950f558442 100644 (file)
 #endif
 #endif
 
-
 struct _LinphoneCallParams{
        LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
        int audio_bw; /* bandwidth limit for audio stream */
+       LinphoneMediaEncryption media_encryption;
        bool_t has_video;
        bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
        bool_t in_conference; /*in conference mode */
        bool_t pad;
+       
 };
 
 struct _LinphoneCall
index b2a0ecd595f126b1225c0d4eddd3cd1e4376546f..86a0fb86b6042688a8b6ea4788f0484527335346 100644 (file)
@@ -112,6 +112,15 @@ typedef struct SalEndpointCandidate{
 
 #define SAL_ENDPOINT_CANDIDATE_MAX 2
 
+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];
+} SalSrtpCryptoAlgo;
+
+#define SAL_CRYPTO_ALGO_MAX 4
+
 typedef struct SalStreamDescription{
        SalMediaProto proto;
        SalStreamType type;
@@ -123,6 +132,7 @@ typedef struct SalStreamDescription{
        int ptime;
        SalEndpointCandidate candidates[SAL_ENDPOINT_CANDIDATE_MAX];
        SalStreamDir dir;
+       SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX];
 } SalStreamDescription;
 
 #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4
index 772997b6b67b876bcb938ac3fe07b2494454b28d..c1bd5c5ac9cda6652bd535cf5e1df31b18466fec 100644 (file)
@@ -514,12 +514,17 @@ static void sdp_process(SalOp *h){
                 It should contains media parameters constraint from the remote offer, not our response*/
                strcpy(h->result->addr,h->base.remote_media->addr);
                h->result->bandwidth=h->base.remote_media->bandwidth;
+               
                for(i=0;i<h->result->nstreams;++i){
                        if (h->result->streams[i].port>0){
                                strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
                                h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
                                h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
                                h->result->streams[i].port=h->base.remote_media->streams[i].port;
+                               
+                               if (h->result->streams[i].proto == SalProtoRtpSavp) {
+                                       h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0]; 
+                               }
                        }
                }
        }
@@ -546,6 +551,9 @@ int sal_call(SalOp *h, const char *from, const char *to){
        sal_op_set_from(h,from);
        sal_op_set_to(h,to);
        sal_exosip_fix_route(h);
+       
+       h->terminated = FALSE;
+
        route = sal_op_get_route(h);
        err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
        if (err!=0){
index 5160777a782ee4f88f07a32eb0046082578f502a..f67fb9cfd714e1f520534b39ac41fd6a2ea49e4d 100644 (file)
@@ -234,9 +234,47 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
                              osip_strdup ("IN"), inet6 ? osip_strdup ("IP6") : osip_strdup ("IP4"),
                              osip_strdup (addr), NULL, NULL);
        }
-       sdp_message_m_media_add (msg, osip_strdup (mt),
-                                int_2char (port), NULL,
-                                osip_strdup ("RTP/AVP"));
+       
+       if (desc->proto == SalProtoRtpSavp) {
+               int i;
+               
+               sdp_message_m_media_add (msg, osip_strdup (mt),
+                                        int_2char (port), NULL,
+                                        osip_strdup ("RTP/SAVP"));
+       
+               /* add crypto lines */
+               for(i=0; i<SAL_CRYPTO_ALGO_MAX; i++) {
+                       char buffer[1024];
+                       switch (desc->crypto[i].algo) {
+                               case AES_128_SHA1_80:
+                                       snprintf(buffer, 1024, "%d %s inline:%s",
+                                               desc->crypto[i].tag, "AES_CM_128_HMAC_SHA1_80", desc->crypto[i].master_key);
+                                       sdp_message_a_attribute_add(msg, lineno, osip_strdup("crypto"),
+                                               osip_strdup(buffer));
+                                       break;
+                               case AES_128_SHA1_32:
+                                       snprintf(buffer, 1024, "%d %s inline:%s",
+                                               desc->crypto[i].tag, "AES_CM_128_HMAC_SHA1_32", desc->crypto[i].master_key);
+                                       sdp_message_a_attribute_add(msg, lineno, osip_strdup("crypto"),
+                                               osip_strdup(buffer));
+                                       break;
+                               case AES_128_NO_AUTH:
+                                       ms_warning("Unsupported crypto suite: AES_128_NO_AUTH");
+                                       break;
+                               case NO_CIPHER_SHA1_80:
+                                       ms_warning("Unsupported crypto suite: NO_CIPHER_SHA1_80");
+                                       break; 
+                               default:
+                                       i = SAL_CRYPTO_ALGO_MAX;
+                       }
+               }
+               
+       } else {
+               sdp_message_m_media_add (msg, osip_strdup (mt),
+                                        int_2char (port), NULL,
+                                        osip_strdup ("RTP/AVP"));
+               
+       }
        if (desc->bandwidth>0) sdp_message_b_bandwidth_add (msg, lineno, osip_strdup ("AS"),
                                     int_2char(desc->bandwidth));
        if (desc->ptime>0) sdp_message_a_attribute_add(msg,lineno,osip_strdup("ptime"),
@@ -356,7 +394,7 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                for(j=0;(sbw=sdp_message_bandwidth_get(msg,i,j))!=NULL;++j){
                        if (strcasecmp(sbw->b_bwtype,"AS")==0) stream->bandwidth=atoi(sbw->b_bandwidth);
                }
-               stream->dir=_sdp_message_get_mline_dir(msg,i);
+               stream->dir=_sdp_message_get_mline_dir(msg,i);          
                /* for each payload type */
                for (j=0;((number=sdp_message_m_payload_get (msg, i,j)) != NULL); j++){
                        const char *rtpmap,*fmtp;
@@ -374,6 +412,49 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                                        pt->send_fmtp ? pt->send_fmtp : "");
                        }
                }
+               
+               /* read crypto lines if any */
+               if (stream->proto == SalProtoRtpSavp) {
+                       int k, valid_count = 0;
+                       sdp_attribute_t *attr;
+                               
+                       memset(&stream->crypto, 0, sizeof(stream->crypto));
+                       for (k=0;valid_count < SAL_CRYPTO_ALGO_MAX && (attr=sdp_message_attribute_get(msg,i,k))!=NULL;k++){
+                               char tmp[256], tmp2[256];
+                               if (keywordcmp("crypto",attr->a_att_field)==0 && attr->a_att_value!=NULL){
+                                       int nb = sscanf(attr->a_att_value, "%d %256s inline:%256s",
+                                               &stream->crypto[valid_count].tag,
+                                               tmp,
+                                               tmp2);
+                                               ms_message("Found valid crypto line (tag:%d algo:'%s' key:'%s'", 
+                                                               stream->crypto[valid_count].tag, 
+                                                               tmp, 
+                                                               tmp2);
+                                       if (nb == 3) {
+                                               if (strcmp(tmp, "AES_CM_128_HMAC_SHA1_80") == 0)
+                                                       stream->crypto[valid_count].algo = AES_128_SHA1_80;
+                                               else if (strcmp(tmp, "AES_CM_128_HMAC_SHA1_32") == 0)
+                                                       stream->crypto[valid_count].algo = AES_128_SHA1_32;
+                                               else {
+                                                       ms_warning("Failed to parse crypto-algo: '%s'", tmp);
+                                                       stream->crypto[valid_count].algo = 0;
+                                               }
+                                               if (stream->crypto[valid_count].algo) {
+                                                       strncpy(stream->crypto[valid_count].master_key, tmp2, 41);
+                                                       stream->crypto[valid_count].master_key[40] = '\0';
+                                                       ms_message("Found valid crypto line (tag:%d algo:'%s' key:'%s'", 
+                                                               stream->crypto[valid_count].tag, 
+                                                               tmp, 
+                                                               stream->crypto[valid_count].master_key);
+                                                       valid_count++;
+                                               }
+                                       } else {
+                                               ms_warning("sdp has a strange a= line (%s) nb=%i",attr->a_att_value,nb);
+                                       }
+                               }
+                       }
+                       ms_message("Found: %d valid crypto lines", valid_count);
+               }
        }
        desc->nstreams=i;
        return 0;
index 852a6f570598831f757dc0ec3e537b17748d2a24..1dc9d47e468fae045aa09132d7829c44ce37e52d 100644 (file)
@@ -78,15 +78,19 @@ static void linphone_gtk_in_call_set_animation_image(GtkWidget *callview, const
        GtkWidget *container=linphone_gtk_get_widget(callview,"in_call_animation");
        GList *elem=gtk_container_get_children(GTK_CONTAINER(container));
        GtkWidget *image;
-       if (!is_stock)
+       
+       if (!is_stock){
+               if (image_name==NULL){
+                       gtk_widget_hide(container);
+               }
                image=create_pixmap(image_name);
-       else
+       }else
                image=gtk_image_new_from_stock(image_name,GTK_ICON_SIZE_DIALOG);
        if (elem)
                gtk_widget_destroy((GtkWidget*)elem->data);
        gtk_widget_show(image);
        gtk_container_add(GTK_CONTAINER(container),image);
-       
+       gtk_widget_show_all(container);
 }
 
 static void linphone_gtk_in_call_set_animation_spinner(GtkWidget *callview){
@@ -97,6 +101,7 @@ static void linphone_gtk_in_call_set_animation_spinner(GtkWidget *callview){
                gtk_widget_destroy((GtkWidget*)elem->data);
        gtk_widget_show(spinner);
        gtk_container_add(GTK_CONTAINER(container),spinner);
+       gtk_widget_set_size_request(spinner, 20,20);
        gtk_spinner_start(GTK_SPINNER(spinner));
 }
 
@@ -421,6 +426,45 @@ void linphone_gtk_in_call_view_enable_audio_view(LinphoneCall *call, gboolean va
        }
 }
 
+void linphone_gtk_auth_token_verified_clicked(GtkButton *button){
+       LinphoneCall *call=linphone_gtk_get_currently_displayed_call(NULL);
+       if (call){
+               linphone_call_set_authentication_token_verified(call,!linphone_call_get_authentication_token_verified(call));
+       }
+}
+
+void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
+       GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
+       GtkWidget *encryption_box=linphone_gtk_get_widget(callview,"encryption_box");
+       GtkWidget *label=linphone_gtk_get_widget(callview,"encryption_label");
+       GtkWidget *status_icon=linphone_gtk_get_widget(callview,"encryption_status_icon");
+       GtkWidget *verify_button=linphone_gtk_get_widget(callview,"encryption_verify_button");
+       LinphoneMediaEncryption me=linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
+       bool_t verified=linphone_call_get_authentication_token_verified(call);
+       switch(me){
+               case LinphoneMediaEncryptionSRTP:
+                       gtk_label_set_markup(GTK_LABEL(label),_("Secured by SRTP"));
+                       gtk_widget_hide(status_icon);
+                       gtk_widget_hide(verify_button);
+                       gtk_widget_show_all(encryption_box);
+               break;
+               case LinphoneMediaEncryptionZRTP:
+               {
+                       gchar *text=g_strdup_printf(_("Secured by ZRTP - [auth token: %s]"),linphone_call_get_authentication_token(call));
+                       gtk_label_set_markup(GTK_LABEL(label),text);
+                       g_free(text);
+                       gtk_image_set_from_stock(GTK_IMAGE(status_icon),
+                                                 verified ? GTK_STOCK_APPLY : GTK_STOCK_DIALOG_WARNING,GTK_ICON_SIZE_MENU);
+                       gtk_button_set_label(GTK_BUTTON(verify_button),
+                                            verified ? _("Set unverified") : _("Set verified"));
+                       gtk_widget_show_all(encryption_box);
+               }       
+               break;
+               default:
+                       gtk_widget_hide(encryption_box);
+       }
+}
+
 void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
        GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
        GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
@@ -444,6 +488,7 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
                g_object_set_data(G_OBJECT(callview),"taskid",GINT_TO_POINTER(taskid));
        }
        linphone_gtk_in_call_view_enable_audio_view(call, !in_conf);
+       linphone_gtk_in_call_view_show_encryption(call);
        if (in_conf) linphone_gtk_set_in_conference(call);
 }
 
index 63564c72ff7661261f913fcb86531e07339f6838..57b56203840013bdc0991b75803bd6af9433df91 100644 (file)
@@ -112,6 +112,7 @@ void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value);
 void linphone_gtk_set_in_conference(LinphoneCall *call);
 void linphone_gtk_unset_from_conference(LinphoneCall *call);
 void linphone_gtk_terminate_conference_participant(LinphoneCall *call);
+void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call);
 typedef float (*get_volume_t)(void *data);
 void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data);
 
index 439005bc5d6c04f71e1f9acaf347d1fe5dd6e0d1..e24fb24cce4c8e764da9cf722caa2cf38ec0dcf0 100644 (file)
@@ -52,7 +52,6 @@ static LinphoneCore *the_core=NULL;
 static GtkWidget *the_ui=NULL;
 
 static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg);
-static void linphone_gtk_show(LinphoneCore *lc);
 static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid);
 static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
 static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username);
@@ -62,6 +61,7 @@ static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
 static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
 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 gboolean linphone_gtk_auto_answer(LinphoneCall *call);
 static void linphone_gtk_status_icon_set_blinking(gboolean val);
 
@@ -126,34 +126,35 @@ static GOptionEntry linphone_options[]={
 
 #ifndef WIN32
 #define CONFIG_FILE ".linphonerc"
+#define SECRETS_FILE ".linphone-zidcache"
 #else
 #define CONFIG_FILE "linphonerc"
+#define SECRETS_FILE "linphone-zidcache"
 #endif
 
 
-
-static char _config_file[1024];
-
-
-const char *linphone_gtk_get_config_file(){
+char *linphone_gtk_get_config_file(const char *filename){
+       const int path_max=1024;
+       char *config_file=g_malloc0(path_max);
+       if (filename==NULL) filename=CONFIG_FILE;
        /*try accessing a local file first if exists*/
        if (access(CONFIG_FILE,F_OK)==0){
-               snprintf(_config_file,sizeof(_config_file),"%s",CONFIG_FILE);
+               snprintf(config_file,path_max,"%s",CONFIG_FILE);
        }else{
 #ifdef WIN32
                const char *appdata=getenv("APPDATA");
                if (appdata){
-                       snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
-                       CreateDirectory(_config_file,NULL);
-                       snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR "\\" CONFIG_FILE);
+                       snprintf(config_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
+                       CreateDirectory(config_file,NULL);
+                       snprintf(config_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename);
                }
 #else
                const char *home=getenv("HOME");
                if (home==NULL) home=".";
-               snprintf(_config_file,sizeof(_config_file),"%s/%s",home,CONFIG_FILE);
+               snprintf(config_file,path_max,"%s/%s",home,filename);
 #endif
        }
-       return _config_file;
+       return config_file;
 }
 
 
@@ -207,10 +208,10 @@ static const char *linphone_gtk_get_factory_config_file(){
 static void linphone_gtk_init_liblinphone(const char *config_file,
                const char *factory_config_file) {
        LinphoneCoreVTable vtable={0};
+       gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE);
 
        vtable.call_state_changed=linphone_gtk_call_state_changed;
        vtable.registration_state_changed=linphone_gtk_registration_state_changed;
-       vtable.show=linphone_gtk_show;
        vtable.notify_presence_recv=linphone_gtk_notify_recv;
        vtable.new_subscription_request=linphone_gtk_new_unknown_subscriber;
        vtable.auth_info_requested=linphone_gtk_auth_info_requested;
@@ -222,10 +223,13 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
        vtable.text_received=linphone_gtk_text_received;
        vtable.refer_received=linphone_gtk_refer_received;
        vtable.buddy_info_updated=linphone_gtk_buddy_info_updated;
+       vtable.call_encryption_changed=linphone_gtk_call_encryption_changed;
 
        linphone_core_set_user_agent("Linphone", LINPHONE_VERSION);
        the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL);
        linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
+       linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
+       g_free(secrets_file);
 }
 
 
@@ -643,12 +647,6 @@ void linphone_gtk_show_main_window(){
        gtk_window_present(GTK_WINDOW(w));
 }
 
-static void linphone_gtk_show(LinphoneCore *lc){
-#ifndef HAVE_NOTIFY
-       linphone_gtk_show_main_window();
-#endif
-}
-
 void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){
        GtkWidget *mw=linphone_gtk_get_main_window();
        if (linphone_core_get_calls(linphone_gtk_get_core())==NULL){
@@ -1038,7 +1036,7 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
                        linphone_gtk_status_icon_set_blinking(FALSE);
                break;
                case LinphoneCallIncomingReceived:
-                       linphone_gtk_create_in_call_view (call);
+                       linphone_gtk_create_in_call_view(call);
                        linphone_gtk_in_call_view_set_incoming(call);
                        linphone_gtk_status_icon_set_blinking(TRUE);
                        if (auto_answer)  {
@@ -1066,6 +1064,10 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
        linphone_gtk_update_call_buttons (call);
 }
 
+static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token){
+       linphone_gtk_in_call_view_show_encryption(call);
+}
+
 static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistrationState rs){
        GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
        GtkTreeModel *model=gtk_combo_box_get_model(box);
@@ -1123,12 +1125,6 @@ static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphonePr
        update_registration_status(cfg,rs);
 }
 
-
-static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
-       GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
-       gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
-}
-
 void linphone_gtk_open_browser(const char *url){
        /*in gtk 2.16, gtk_show_uri does not work...*/
 #ifndef WIN32
@@ -1149,6 +1145,13 @@ void linphone_gtk_link_to_website(GtkWidget *item){
        linphone_gtk_open_browser(home);
 }
 
+#ifndef HAVE_GTK_OSX
+
+static void icon_popup_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer user_data){
+       GtkWidget *menu=(GtkWidget*)g_object_get_data(G_OBJECT(status_icon),"menu");
+       gtk_menu_popup(GTK_MENU(menu),NULL,NULL,gtk_status_icon_position_menu,status_icon,button,activate_time);
+}
+
 static GtkWidget *create_icon_menu(){
        GtkWidget *menu=gtk_menu_new();
        GtkWidget *menu_item;
@@ -1226,18 +1229,30 @@ static gboolean do_icon_blink(GtkStatusIcon *gi){
        return TRUE;
 }
 
+#endif
+
 static void linphone_gtk_status_icon_set_blinking(gboolean val){
-       guint tout;
-       tout=(unsigned)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon),"timeout"));
-       if (val && tout==0){
-               tout=g_timeout_add(500,(GSourceFunc)do_icon_blink,icon);
-               g_object_set_data(G_OBJECT(icon),"timeout",GINT_TO_POINTER(tout));
-       }else if (!val && tout!=0){
-               GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(icon),"icon");
-               g_source_remove(tout);
-               g_object_set_data(G_OBJECT(icon),"timeout",NULL);
-               gtk_status_icon_set_from_pixbuf(icon,normal_icon);
+#ifdef HAVE_GTK_OSX
+       static gint attention_id;
+       GtkOSXApplication *theMacApp=(GtkOSXApplication*)g_object_new(GTK_TYPE_OSX_APPLICATION, NULL);
+       if (val)
+               attention_id=gtk_osxapplication_attention_request(theMacApp,CRITICAL_REQUEST);
+       else gtk_osxapplication_cancel_attention_request(theMacApp,attention_id);
+#else
+       if (icon!=NULL){
+               guint tout;
+               tout=(unsigned)GPOINTER_TO_INT(g_object_get_data(G_OBJECT(icon),"timeout"));
+               if (val && tout==0){
+                       tout=g_timeout_add(500,(GSourceFunc)do_icon_blink,icon);
+                       g_object_set_data(G_OBJECT(icon),"timeout",GINT_TO_POINTER(tout));
+               }else if (!val && tout!=0){
+                       GdkPixbuf *normal_icon=g_object_get_data(G_OBJECT(icon),"icon");
+                       g_source_remove(tout);
+                       g_object_set_data(G_OBJECT(icon),"timeout",NULL);
+                       gtk_status_icon_set_from_pixbuf(icon,normal_icon);
+               }
        }
+#endif
 }
 
 static void init_identity_combo(GtkComboBox *box){
@@ -1586,7 +1601,7 @@ int main(int argc, char *argv[]){
 #ifdef ENABLE_NLS
        void *p;
 #endif
-       const char *config_file;
+       char *config_file;
        const char *factory_config_file;
        const char *lang;
        GtkSettings *settings;
@@ -1598,7 +1613,7 @@ int main(int argc, char *argv[]){
        
        progpath = strdup(argv[0]);
        
-       config_file=linphone_gtk_get_config_file();
+       config_file=linphone_gtk_get_config_file(NULL);
        
 
 #ifdef WIN32
index 9c393b54c76405c7bc29aeae2bd73f31610a3e59..0448795f71a1ad7db44c55467d493f80d1a852c2 100644 (file)
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <requires lib="gtk+" version="2.22"/>
   <object class="GtkWindow" id="dummy_conf_window">
     <property name="can_focus">False</property>
     <child>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <child>
-                  <object class="GtkHBox" id="incall_hbox1">
+                  <object class="GtkVBox" id="in_call_animation">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkVBox" id="in_call_animation">
+                      <placeholder/>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="in_call_uri">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">label</property>
+                    <property name="justify">center</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="encryption_box">
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkImage" id="image12">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <child>
-                          <placeholder/>
-                        </child>
+                        <property name="stock">gtk-dialog-authentication</property>
+                        <property name="icon-size">1</property>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
                         <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="in_call_uri">
+                      <object class="GtkImage" id="encryption_status_icon">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="stock">gtk-apply</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="encryption_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="label" translatable="yes">label</property>
-                        <property name="justify">center</property>
                       </object>
                       <packing>
                         <property name="expand">True</property>
                         <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="encryption_verify_button">
+                        <property name="label" translatable="yes">Set verified</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_action_appearance">False</property>
+                        <signal name="clicked" handler="linphone_gtk_auth_token_verified_clicked" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="expand">True</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
                 <child>
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">1</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
                 <child>
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">2</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
                 <child>
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">False</property>
-                    <property name="position">3</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
               </object>
                                     <property name="invisible_char">●</property>
                                     <property name="primary_icon_activatable">False</property>
                                     <property name="secondary_icon_activatable">False</property>
-                                    <property name="primary_icon_sensitive">True</property>
-                                    <property name="secondary_icon_sensitive">True</property>
                                     <signal name="activate" handler="linphone_gtk_uri_bar_activate" swapped="no"/>
                                   </object>
                                   <packing>
                                     <property name="invisible_char_set">True</property>
                                     <property name="primary_icon_activatable">False</property>
                                     <property name="secondary_icon_activatable">False</property>
-                                    <property name="primary_icon_sensitive">True</property>
-                                    <property name="secondary_icon_sensitive">True</property>
                                     <signal name="changed" handler="linphone_gtk_show_friends" swapped="no"/>
                                   </object>
                                   <packing>
                               <object class="GtkScrolledWindow" id="scrolledwindow1">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="hscrollbar_policy">automatic</property>
-                                <property name="vscrollbar_policy">automatic</property>
                                 <child>
                                   <object class="GtkTreeView" id="contact_list">
                                     <property name="visible">True</property>
                                     <signal name="cursor-changed" handler="linphone_gtk_contact_clicked" swapped="no"/>
                                     <signal name="row-activated" handler="linphone_gtk_contact_activated" swapped="no"/>
                                     <signal name="popup-menu" handler="linphone_gtk_popup_contact_menu" swapped="no"/>
+                                    <child internal-child="selection">
+                                      <object class="GtkTreeSelection" id="treeview-selection1"/>
+                                    </child>
                                   </object>
                                 </child>
                               </object>
                                         <property name="invisible_char_set">True</property>
                                         <property name="primary_icon_activatable">False</property>
                                         <property name="secondary_icon_activatable">False</property>
-                                        <property name="primary_icon_sensitive">True</property>
-                                        <property name="secondary_icon_sensitive">True</property>
                                         <signal name="activate" handler="linphone_gtk_directory_search_activate" swapped="no"/>
                                         <signal name="icon-press" handler="linphone_gtk_directory_search_activate" swapped="no"/>
                                         <signal name="focus-in-event" handler="linphone_gtk_directory_search_focus_in" swapped="no"/>
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
                                 <property name="hscrollbar_policy">never</property>
-                                <property name="vscrollbar_policy">automatic</property>
                                 <child>
                                   <object class="GtkTreeView" id="logs_view">
                                     <property name="visible">True</property>
                                     <property name="can_focus">True</property>
                                     <property name="headers_visible">False</property>
                                     <signal name="row-activated" handler="linphone_gtk_history_row_activated" swapped="no"/>
+                                    <child internal-child="selection">
+                                      <object class="GtkTreeSelection" id="treeview-selection2"/>
+                                    </child>
                                   </object>
                                 </child>
                               </object>
                                         <property name="invisible_char">●</property>
                                         <property name="primary_icon_activatable">False</property>
                                         <property name="secondary_icon_activatable">False</property>
-                                        <property name="primary_icon_sensitive">True</property>
-                                        <property name="secondary_icon_sensitive">True</property>
                                       </object>
                                       <packing>
                                         <property name="left_attach">1</property>
                                         <property name="invisible_char">●</property>
                                         <property name="primary_icon_activatable">False</property>
                                         <property name="secondary_icon_activatable">False</property>
-                                        <property name="primary_icon_sensitive">True</property>
-                                        <property name="secondary_icon_sensitive">True</property>
                                       </object>
                                       <packing>
                                         <property name="left_attach">1</property>
index ce9373dae81446bc5ce26536c5cc13a1ae3e69d5..4006226325637746a40dd22cc9306d4865c317d5 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
+  <requires lib="gtk+" version="2.22"/>
   <object class="GtkAdjustment" id="adjustment1">
     <property name="lower">500</property>
     <property name="upper">3001</property>
@@ -53,6 +53,7 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
+  <object class="GtkListStore" id="liststore1"/>
   <object class="GtkListStore" id="model1">
     <columns>
       <!-- column-name gchararray -->
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkVBox" id="vbox6">
+                          <object class="GtkTable" id="table1">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="n_rows">4</property>
+                            <property name="n_columns">2</property>
                             <child>
-                              <placeholder/>
+                              <object class="GtkComboBox" id="proto_combo">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="model">model8</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="renderer1"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="proto_port">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">•</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="primary_icon_activatable">False</property>
+                                <property name="secondary_icon_activatable">False</property>
+                                <property name="adjustment">adjustment7</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="video_rtp_port">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="invisible_char">•</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="primary_icon_activatable">False</property>
+                                <property name="secondary_icon_activatable">False</property>
+                                <property name="adjustment">adjustment2</property>
+                                <signal name="value-changed" handler="linphone_gtk_video_port_changed" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                              </packing>
                             </child>
                             <child>
-                              <object class="GtkTable" id="table1">
+                              <object class="GtkSpinButton" id="audio_rtp_port">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="invisible_char">•</property>
+                                <property name="invisible_char_set">True</property>
+                                <property name="primary_icon_activatable">False</property>
+                                <property name="secondary_icon_activatable">False</property>
+                                <property name="adjustment">adjustment3</property>
+                                <signal name="value-changed" handler="linphone_gtk_audio_port_changed" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label7">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
                                 <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                <property name="n_rows">3</property>
-                                <property name="n_columns">2</property>
-                                <child>
-                                  <object class="GtkComboBox" id="proto_combo">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="model">model8</property>
-                                    <signal name="changed" handler="linphone_gtk_proto_changed" swapped="no"/>
-                                    <child>
-                                      <object class="GtkCellRendererText" id="renderer1"/>
-                                      <attributes>
-                                        <attribute name="text">0</attribute>
-                                      </attributes>
-                                    </child>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinButton" id="proto_port">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="invisible_char">•</property>
-                                    <property name="invisible_char_set">True</property>
-                                    <property name="primary_icon_activatable">False</property>
-                                    <property name="secondary_icon_activatable">False</property>
-                                    <property name="adjustment">adjustment7</property>
-                                    <signal name="value-changed" handler="linphone_gtk_update_my_port" swapped="no"/>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinButton" id="video_rtp_port">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="invisible_char">•</property>
-                                    <property name="invisible_char_set">True</property>
-                                    <property name="primary_icon_activatable">False</property>
-                                    <property name="secondary_icon_activatable">False</property>
-                                    <property name="adjustment">adjustment2</property>
-                                    <signal name="value-changed" handler="linphone_gtk_video_port_changed" swapped="no"/>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                    <property name="top_attach">1</property>
-                                    <property name="bottom_attach">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkSpinButton" id="audio_rtp_port">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">True</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="invisible_char">•</property>
-                                    <property name="invisible_char_set">True</property>
-                                    <property name="primary_icon_activatable">False</property>
-                                    <property name="secondary_icon_activatable">False</property>
-                                    <property name="adjustment">adjustment3</property>
-                                    <signal name="value-changed" handler="linphone_gtk_audio_port_changed" swapped="no"/>
-                                  </object>
-                                  <packing>
-                                    <property name="left_attach">1</property>
-                                    <property name="right_attach">2</property>
-                                    <property name="top_attach">2</property>
-                                    <property name="bottom_attach">3</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="label7">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="label" translatable="yes">Video RTP/UDP:</property>
-                                    <property name="justify">right</property>
-                                  </object>
-                                  <packing>
-                                    <property name="top_attach">1</property>
-                                    <property name="bottom_attach">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="label6">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                                    <property name="label" translatable="yes">Audio RTP/UDP:</property>
-                                    <property name="justify">right</property>
-                                  </object>
-                                  <packing>
-                                    <property name="top_attach">2</property>
-                                    <property name="bottom_attach">3</property>
-                                  </packing>
-                                </child>
+                                <property name="label" translatable="yes">Video RTP/UDP:</property>
+                                <property name="justify">right</property>
                               </object>
                               <packing>
-                                <property name="expand">True</property>
-                                <property name="fill">True</property>
-                                <property name="position">1</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label6">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <property name="label" translatable="yes">Audio RTP/UDP:</property>
+                                <property name="justify">right</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="media_encryption_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="label" translatable="yes">Media encryption type</property>
+                              </object>
+                              <packing>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkComboBox" id="media_encryption_combo">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="active">0</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
                               </packing>
                             </child>
                           </object>
index 78a8ca4230f05c1d84431752a3c1855bbb88ca25..8bacff9f55fd359f62d5f6102909ec83760ceadf 100644 (file)
@@ -803,6 +803,72 @@ void linphone_gtk_ui_level_toggled(GtkWidget *w) {
        linphone_gtk_ui_level_adapt(top);
 }
 
+static void linphone_gtk_media_encryption_changed(GtkWidget *combo){
+       char *selected=gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
+       LinphoneCore *lc=linphone_gtk_get_core();
+       if (selected!=NULL){
+               if (strcasecmp(selected,"SRTP")==0)
+                       linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionSRTP);
+               else if (strcasecmp(selected,"ZRTP")==0)
+                       linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionZRTP);
+               else linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionNone);
+               g_free(selected);
+       }else g_warning("gtk_combo_box_get_active_text() returned NULL");
+}
+
+static void linphone_gtk_show_media_encryption(GtkWidget *pb){
+       LinphoneCore *lc=linphone_gtk_get_core();
+       GtkWidget *combo=linphone_gtk_get_widget(pb,"media_encryption_combo");
+       bool_t no_enc=TRUE;
+       int srtp_id=-1,zrtp_id=-1;
+       GtkTreeModel *model;
+       GtkListStore *store;
+       GtkTreeIter iter;
+       GtkCellRenderer *renderer=gtk_cell_renderer_text_new();
+       
+       model=GTK_TREE_MODEL((store=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,"text",0,NULL);
+       
+       gtk_list_store_append(store,&iter);
+       gtk_list_store_set(store,&iter,0,_("None"),-1);
+       
+       if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionSRTP)){
+               gtk_list_store_append(store,&iter);
+               gtk_list_store_set(store,&iter,0,_("SRTP"),-1);
+               srtp_id=1;
+               no_enc=FALSE;
+       }
+       if (linphone_core_media_encryption_supported(lc,LinphoneMediaEncryptionZRTP)){
+               gtk_list_store_append(store,&iter);
+               gtk_list_store_set(store,&iter,0,_("ZRTP"),-1);
+               no_enc=FALSE;
+               if (srtp_id!=-1) zrtp_id=2;
+               else zrtp_id=1;
+       }
+       if (no_enc){
+               /*hide this setting*/
+               gtk_widget_hide(combo);
+               gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_label"));
+       }else{
+               LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc);
+               switch(menc){
+                       case LinphoneMediaEncryptionNone:
+                               gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0);
+                       break;
+                       case LinphoneMediaEncryptionSRTP:
+                               if (srtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),srtp_id);
+                       break;
+                       case LinphoneMediaEncryptionZRTP:
+                               if (zrtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),zrtp_id);
+                       break;
+               }
+               g_signal_connect(G_OBJECT(combo),"changed",(GCallback)linphone_gtk_media_encryption_changed,NULL);
+       }
+       g_object_unref(G_OBJECT(model));
+}
+
 void linphone_gtk_show_parameters(void){
        GtkWidget *pb=linphone_gtk_create_window("parameters");
        LinphoneCore *lc=linphone_gtk_get_core();
@@ -841,6 +907,8 @@ void linphone_gtk_show_parameters(void){
        gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(pb,"video_rtp_port")),
                                linphone_core_get_video_port(lc));
 
+       linphone_gtk_show_media_encryption(pb);
+       
        tmp=linphone_core_get_nat_address(lc);
        if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"nat_address")),tmp);
        tmp=linphone_core_get_stun_server(lc);
@@ -916,5 +984,7 @@ 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);
        gtk_widget_show(pb);
 }
index b4a3866787bed30579594b1820b6ec2568f5fe9d..1c4b0e85b23073f7d3af1cd12f6b4a48e20bd0a1 100644 (file)
@@ -223,6 +223,5 @@ public interface LinphoneCall {
        
        String getAuthenticationToken();
        boolean isAuthenticationTokenVerified();
-       boolean areStreamsEncrypted();
        boolean isInConference();
 }
index 78a63d3fa9fd495fad08b3862af2507d3b275edf..c3bdc43ec8439e18da622cb2ba5068b154a7e038 100644 (file)
@@ -35,4 +35,15 @@ public interface LinphoneCallParams {
         */
        void setAudioBandwidth(int value);
        
+       /**
+        * return selected media encryption
+        * @return 'none', 'srtp' or 'zrtp'
+        */
+       String getMediaEncryption();
+       /**
+        * set media encryption (rtp) to use
+        * @params menc: 'none', 'srtp' or 'zrtp'
+        */
+       void setMediaEnctyption(String menc);
+       
 }
index 88f1be6fff35ac58ccfdf000f2b4766f62d65549..944fa026d2f5f3956ab6c7fd7442733b550edfba 100644 (file)
@@ -623,5 +623,34 @@ public interface LinphoneCore {
        LinphoneCall findCallFromUri(String uri);
 
        int getMaxCalls();
+       void setMaxCalls(int max);
+       boolean isMyself(String uri);
 
+       /**
+        * Use this method to check the calls state and forbid proposing actions
+        * which could result in an active call.
+        * Eg: don't start a new call if one is in outgoing ringing.
+        * Eg: don't merge to conference either as it could result
+        *     in two active calls (conference and accepted call). 
+        * @return
+        */
+       boolean soundResourcesLocked();
+       /**
+        * set media encryption (rtp) to use
+        * @params menc: 'none', 'srtp' or 'zrtp'
+        */
+       void setMediaEncryption(String menc);
+       /**
+        * return selected media encryption
+        * @return 'none', 'srtp' or 'zrtp'
+        */
+       String getMediaEncryption();
+/**
+        * Set media encryption required for outgoing calls
+        */
+       void setMediaEncryptionMandatory(boolean yesno);
+       /**
+        * @return if media encryption is required for ougtoing calls
+        */
+       boolean isMediaEncryptionMandatory();
 }
index de01182cafcdce11acb815ad47551f13fd0f8f66..4a5fb506758a10bb9b071c6fd8a4b1c0edc86e0b 100755 (executable)
@@ -1,9 +1,11 @@
 ./bin/avcodec-53.dll
 ./bin/avutil-51.dll
-./bin/libeXosip2-6.dll
+./bin/libeay32.dll
+./bin/ssleay32.dll
+./bin/libeXosip2-7.dll
 ./bin/libogg-0.dll
 ./bin/libtheora-0.dll
 ./bin/libxml2-2.dll
-./bin/libosip2-6.dll
-./bin/libosipparser2-6.dll
+./bin/libosip2-7.dll
+./bin/libosipparser2-7.dll
 ./bin/swscale-2.dll
index 7e80b7c99175ff4165814eaa90d13a7b1bd7a869..4ee916b3fcae0aba38a0d595079298242c9ac2cd 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 7e80b7c99175ff4165814eaa90d13a7b1bd7a869
+Subproject commit 4ee916b3fcae0aba38a0d595079298242c9ac2cd
diff --git a/oRTP b/oRTP
index 7606207905bd3dc661e68576097adce471916697..de8ecee12b217f5e63e12fdfe1e3462e248ad46d 160000 (submodule)
--- a/oRTP
+++ b/oRTP
@@ -1 +1 @@
-Subproject commit 7606207905bd3dc661e68576097adce471916697
+Subproject commit de8ecee12b217f5e63e12fdfe1e3462e248ad46d
index cdf0028e670ac5ba56ceefce4c88658d70925154..b1cf01dcb537ca5b38c9b0e6a888ad0c86e19328 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -592,8 +592,8 @@ msgid "Lookup:"
 msgstr "Rechercher:"
 
 #: ../gtk/main.ui.h:43
-msgid "My current identity:"
-msgstr "Mon identité sip :"
+msgid "My current default identity:"
+msgstr "Mon identité sip par défaut :"
 
 #: ../gtk/main.ui.h:44
 msgid "Online users"