diff --git a/README.zrtp b/README.zrtp new file mode 100644 index 000000000..c71c8d2d7 --- /dev/null +++ b/README.zrtp @@ -0,0 +1,94 @@ +ZRTP guide + +== Downloads == +- SRTP +http://sourceforge.net/projects/srtp/ +or "apt-get source libsrtp0" on Debian + +- ZRTP (libzrtpcpp-2.0) +http://www.gnutelephony.org/index.php/GNU_ZRTP + + +== Patch libzrtpcpp == +Index: src/ZIDFile.cpp +=================================================================== +--- src/ZIDFile.cpp (révision 754) ++++ src/ZIDFile.cpp (copie de travail) +@@ -78,10 +78,11 @@ + + // create save file name, rename and re-open + // if rename fails, just unlink old ZID file and create a brand new file +- // just a little inconnvenience for the user, need to verify new SAS ++ // just a little inconvenience for the user, need to verify new SAS + std::string fn = std::string(name) + std::string(".save"); + if (rename(name, fn.c_str()) < 0) { +- unlink(name); ++ // unlink(name); + createZIDFile(name); + return; + } +Index: src/libzrtpcpp/ZrtpCallback.h +=================================================================== +--- src/libzrtpcpp/ZrtpCallback.h (révision 754) ++++ src/libzrtpcpp/ZrtpCallback.h (copie de travail) +@@ -27,7 +27,7 @@ + + #include + #include +-#include ++//#include + #include + + /** +Index: src/libzrtpcpp/ZIDRecord.h +=================================================================== +--- src/libzrtpcpp/ZIDRecord.h (révision 754) ++++ src/libzrtpcpp/ZIDRecord.h (copie de travail) +@@ -33,7 +33,7 @@ + + #include + #include +-#include ++//#include + + #define IDENTIFIER_LEN 12 + #define RS_LENGTH 32 +Index: CMakeLists.txt +=================================================================== +--- CMakeLists.txt (révision 754) ++++ CMakeLists.txt (copie de travail) +@@ -124,11 +124,15 @@ + if(CMAKE_COMPILER_IS_GNUCXX) + add_definitions(-Wno-long-long -Wno-char-subscripts) + add_definitions(-Wall -ansi -pedantic) ++ add_definitions(-DNEW_STDCPP) + endif() + + add_subdirectory(src) +-add_subdirectory(demo) + ++if (enable_ccrtp) ++ add_subdirectory(demo) ++endif() ++ + if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package/) + MESSAGE(STATUS "package dir not found") + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/) + + + +== Create simlinks or move folders == +submodules/external/srtp -> path_to_your_srtp_source +submodules/external/libzrtpcpp -> path_to_your_patched_zrtpcpp_source + + + +== Compilation for Android == +ndk-build BUILD_GPLV3_ZRTP=1 -j5 + + +== Compilation for Desktop version == +First ortp: ./autogen.sh && ./configure --enable-zrtp && make -j5 && sudo make install +Then mediastreamer2: ./autogen.sh && ./configure && make -j5 && sudo make install +Finally linphone: ./autogen.sh && ./configure --enable-external-ortp && make -j5 && sudo make install + diff --git a/build/android/Android.mk b/build/android/Android.mk index 468afbfa3..28878a5bc 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -61,8 +61,7 @@ LOCAL_CFLAGS += \ -DENABLE_TRACE \ -DLINPHONE_VERSION=\"3.4.0\" \ -DLINPHONE_PLUGINS_DIR=\"\\tmp\" \ - -DLOG_DOMAIN=$(MY_LOG_DOMAIN) \ - -UNE_BONNE_PIPE_CA_FAIT_DU_BIEN + -DLOG_DOMAIN=$(MY_LOG_DOMAIN) LOCAL_CFLAGS += -DIN_LINPHONE @@ -103,10 +102,11 @@ LOCAL_STATIC_LIBRARIES += \ endif ifeq ($(LINPHONE_VIDEO),1) +LOCAL_STATIC_LIBRARIES += libvpx ifeq ($(BUILD_X264),1) LOCAL_STATIC_LIBRARIES += \ libmsx264 \ - libx264 + libx264 endif LOCAL_SHARED_LIBRARIES += \ libavcodec \ @@ -127,6 +127,29 @@ LOCAL_SRC_FILES += $(LIBLINPHONE_EXTENDED_SRC_FILES) LOCAL_C_INCLUDES += $(LIBLINPHONE_EXTENDED_C_INCLUDES) endif +LOCAL_LDLIBS += -lGLESv2 +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + LOCAL_SHARED_LIBRARIES += liblinssl liblincrypto + ifeq ($(BUILD_GPLV3_ZRTP),1) + LOCAL_SHARED_LIBRARIES += libzrtpcpp + endif + + ifeq ($(BUILD_SRTP),1) + LOCAL_SHARED_LIBRARIES += libsrtp + endif +else + LOCAL_LDLIBS += -lz + #LOCAL_STATIC_LIBRARIES += libz libdl + LOCAL_STATIC_LIBRARIES += \ + libssl-static libcrypto-static + ifeq ($(BUILD_GPLV3_ZRTP),1) + LOCAL_STATIC_LIBRARIES += libzrtpcpp-static + endif + + ifeq ($(BUILD_SRTP),1) + LOCAL_STATIC_LIBRARIES += libsrtp-static + endif +endif LOCAL_MODULE := liblinphone include $(BUILD_SHARED_LIBRARY) diff --git a/console/commands.c b/console/commands.c index 867e4b867..32482bad7 100644 --- a/console/commands.c +++ b/console/commands.c @@ -90,6 +90,7 @@ static int lpc_cmd_pause(LinphoneCore *lc, char *args); static int lpc_cmd_resume(LinphoneCore *lc, char *args); static int lpc_cmd_mute_mic(LinphoneCore *lc, char *args); static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args); +static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args); static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args); #ifdef VIDEO_ENABLED static int lpc_cmd_camera(LinphoneCore *lc, char *args); @@ -192,6 +193,8 @@ static LPC_COMMAND commands[] = { #endif { "unmute", lpc_cmd_unmute_mic, "Unmute microphone and resume voice transmission."}, + { "playbackgain", lpc_cmd_playback_gain, + "Adjust playback gain."}, { "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL }, { "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode", @@ -2303,6 +2306,15 @@ static int lpc_cmd_unmute_mic(LinphoneCore *lc, char *args){ return 1; } +static int lpc_cmd_playback_gain(LinphoneCore *lc, char *args) +{ + if (args){ + linphone_core_set_playback_gain_db(lc, atof(args)); + return 1; + } + return 0; +} + static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args) { bool_t rtp_xmit_off=FALSE; diff --git a/console/linphonec.c b/console/linphonec.c index 40a243607..f4d855574 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -323,6 +323,17 @@ static void linphonec_call_updated(LinphoneCall *call){ } } +static void linphonec_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t encrypted, const char *auth_token) { + long id=(long)linphone_call_get_user_pointer (call); + if (!encrypted) { + linphonec_out("Call %i is not fully encrypted and auth token is %s.\n", id, + (auth_token != NULL) ? auth_token : "absent"); + } else { + linphonec_out("Call %i is fully encrypted and auth token is %s.\n", id, + (auth_token != NULL) ? auth_token : "absent"); + } +} + static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState st, const char *msg){ char *from=linphone_call_get_remote_address_as_string(call); long id=(long)linphone_call_get_user_pointer (call); @@ -626,6 +637,7 @@ main (int argc, char *argv[]) { linphonec_vtable.dtmf_received=linphonec_dtmf_received; linphonec_vtable.refer_received=linphonec_display_refer; linphonec_vtable.notify_recv=linphonec_notify_received; + linphonec_vtable.call_encryption_changed=linphonec_call_encryption_changed; if (! linphonec_init(argc, argv) ) exit(EXIT_FAILURE); diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java index d5351d99c..e7db170b8 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialBuddyStatus.java @@ -97,7 +97,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} - + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public static void main(String[] args) { @@ -231,5 +231,4 @@ public class TutorialBuddyStatus implements LinphoneCoreListener { } - } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index 9309779bf..5837876cb 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -75,7 +75,7 @@ public class TutorialChatRoom implements LinphoneCoreListener { public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg){} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} - + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) { write("Message ["+message+"] received from ["+from.asString()+"]"); diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java index d9fdd4f41..30510fd84 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialHelloWorld.java @@ -69,6 +69,8 @@ public class TutorialHelloWorld implements LinphoneCoreListener { public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} + /* * Call state notification listener */ diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java index c00ff9b73..8af45162c 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialRegistration.java @@ -80,6 +80,7 @@ public class TutorialRegistration implements LinphoneCoreListener { public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) {} public void callState(LinphoneCore lc, LinphoneCall call, State cstate, String msg) {} public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,int delay_ms, Object data) {} + public void callEncryptionChanged(LinphoneCore lc, LinphoneCall call,boolean encrypted, String authenticationToken) {} public static void main(String[] args) { // Check tutorial was called with the right number of arguments diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7e6e0380a..ee69c93dc 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sipsetup.h" #include "lpconfig.h" #include "private.h" +#include #include "mediastreamer2/mediastream.h" @@ -40,6 +41,100 @@ static MSWebCam *get_nowebcam_device(){ } #endif +static const char* get_zrtp_identifier(LinphoneCore *lc){ + const char *confZid=lp_config_get_string(lc->config,"rtp","zid",NULL); + if (confZid != NULL) { + return confZid; + } else { + int32_t *zid=calloc(3,32); + int i=0; + for(;i<3;i++) { + zid[i]=rand(); + } + lp_config_set_string(lc->config,"rtp","zid",(char*)zid); + return lp_config_get_string(lc->config,"rtp","zid",NULL); + } +} + +const char* linphone_call_get_authentication_token(LinphoneCall *call){ + return call->auth_token; +} + +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) { + // Check ZRTP encryption in audiostream + if (!call->audiostream_encrypted) { + return FALSE; + } + +#ifdef VIDEO_ENABLED + // If video enabled, check ZRTP encryption in videostream + const LinphoneCallParams *params=linphone_call_get_current_params(call); + if (params->has_video && !call->videostream_encrypted) { + return FALSE; + } +#endif + + return TRUE; +} + +void propagate_encryption_changed(LinphoneCall *call){ + if (call->core->vtable.call_encryption_changed == NULL) return; + + 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); + } else { + ms_message("All streams are encrypted"); + call->core->vtable.call_encryption_changed(call->core, call, TRUE, call->auth_token); + } +} + +#ifdef VIDEO_ENABLED +static void linphone_call_videostream_encryption_changed(void *data, bool_t encrypted){ + ms_message("Video stream is %s", encrypted ? "encrypted" : "not encrypted"); + + LinphoneCall *call = (LinphoneCall *)data; + call->videostream_encrypted=encrypted; + propagate_encryption_changed(call); +} +#endif + +static void linphone_call_audiostream_encryption_changed(void *data, bool_t encrypted) { + ms_message("Audio stream is %s ", encrypted ? "encrypted" : "not encrypted"); + + LinphoneCall *call = (LinphoneCall *)data; + call->audiostream_encrypted=encrypted; + propagate_encryption_changed(call); + + +#ifdef VIDEO_ENABLED + // Enable video encryption + const LinphoneCallParams *params=linphone_call_get_current_params(call); + if (params->has_video) { + ms_message("Trying to enable encryption on video stream"); + OrtpZrtpParams params; + params.zid=get_zrtp_identifier(call->core); + params.zid_file=NULL; //unused + video_stream_enable_zrtp(call->videostream,call->audiostream,¶ms); + } +#endif +} + + +static void linphone_call_audiostream_auth_token_ready(void *data, const char* auth_token, bool_t verified) { + LinphoneCall *call=(LinphoneCall *)data; + if (call->auth_token != NULL) + ms_free(call->auth_token); + + call->auth_token=ms_strdup(auth_token); + call->auth_token_verified=verified; + + ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified"); +} + static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){ MSList *l=NULL; @@ -357,6 +452,10 @@ static void linphone_call_destroy(LinphoneCall *obj) } if (obj->owns_call_log) linphone_call_log_destroy(obj->log); + if (obj->auth_token) { + ms_free(obj->auth_token); + } + ms_free(obj); } @@ -673,6 +772,9 @@ void linphone_call_init_media_streams(LinphoneCall *call){ if (lc->a_rtp) rtp_session_set_transports(audiostream->session,lc->a_rtp,lc->a_rtcp); + call->audiostream_app_evq = ortp_ev_queue_new(); + rtp_session_register_event_queue(audiostream->session,call->audiostream_app_evq); + #ifdef VIDEO_ENABLED if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].port>0){ @@ -682,6 +784,8 @@ void linphone_call_init_media_streams(LinphoneCall *call){ video_stream_set_event_callback(call->videostream,video_stream_event_cb, call); if (lc->v_rtp) rtp_session_set_transports(call->videostream->session,lc->v_rtp,lc->v_rtcp); + call->videostream_app_evq = ortp_ev_queue_new(); + rtp_session_register_event_queue(call->videostream->session,call->videostream_app_evq); #ifdef TEST_EXT_RENDERER video_stream_set_render_callback(call->videostream,rendercb,NULL); #endif @@ -1017,6 +1121,13 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut call->playing_ringbacktone=send_ringbacktone; call->up_bw=linphone_core_get_upload_bandwidth(lc); + if (ortp_zrtp_available()) { + OrtpZrtpParams params; + params.zid=get_zrtp_identifier(lc); + params.zid_file=lc->zrtp_secrets_cache; + audio_stream_enable_zrtp(call->audiostream,¶ms); + } + goto end; end: ms_free(cname); @@ -1030,6 +1141,10 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){ void linphone_call_stop_media_streams(LinphoneCall *call){ if (call->audiostream!=NULL) { + rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq); + ortp_ev_queue_flush(call->audiostream_app_evq); + ortp_ev_queue_destroy(call->audiostream_app_evq); + if (call->audiostream->ec){ const char *state_str=NULL; ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_GET_STATE_STRING,&state_str); @@ -1042,8 +1157,13 @@ void linphone_call_stop_media_streams(LinphoneCall *call){ audio_stream_stop(call->audiostream); call->audiostream=NULL; } + + #ifdef VIDEO_ENABLED if (call->videostream!=NULL){ + rtp_session_unregister_event_queue(call->videostream->session,call->videostream_app_evq); + ortp_ev_queue_flush(call->videostream_app_evq); + ortp_ev_queue_destroy(call->videostream_app_evq); video_stream_stop(call->videostream); call->videostream=NULL; } @@ -1225,11 +1345,44 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse ms_message("Thread processing load: audio=%f\tvideo=%f",audio_load,video_load); } #ifdef VIDEO_ENABLED - if (call->videostream!=NULL) + if (call->videostream!=NULL) { + // Beware that the application queue should not depend on treatments fron the + // mediastreamer queue. video_stream_iterate(call->videostream); + + if (call->videostream_app_evq){ + OrtpEvent *ev; + while (NULL != (ev=ortp_ev_queue_get(call->videostream_app_evq))){ + OrtpEventType evt=ortp_event_get_type(ev); + if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_videostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); + } + ortp_event_destroy(ev); + } + } + } #endif - if (call->audiostream!=NULL) + if (call->audiostream!=NULL) { + // Beware that the application queue should not depend on treatments fron the + // mediastreamer queue. audio_stream_iterate(call->audiostream); + + if (call->audiostream->evq){ + OrtpEvent *ev; + while (NULL != (ev=ortp_ev_queue_get(call->audiostream_app_evq))){ + OrtpEventType evt=ortp_event_get_type(ev); + if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_audiostream_encryption_changed(call, evd->info.zrtp_stream_encrypted); + } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) { + OrtpEventData *evd=ortp_event_get_data(ev); + linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified); + } + ortp_event_destroy(ev); + } + } + } if (one_second_elapsed && call->audiostream!=NULL && disconnect_timeout>0 ) disconnected=!audio_stream_alive(call->audiostream,disconnect_timeout); if (disconnected) @@ -1268,3 +1421,4 @@ void linphone_call_log_completed(LinphoneCall *call){ call_logs_write_to_config_file(lc); } + diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 298805287..116fc4dff 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -487,6 +487,11 @@ static void sip_config_read(LinphoneCore *lc) } else { tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",0); } + if (lp_config_get_int(lc->config,"sip","sip_tls_random_port",0)) { + tr.tls_port=(0xDFF&+random())+1024; + } else { + tr.tls_port=lp_config_get_int(lc->config,"sip","sip_tls_port",0); + } /*start listening on ports*/ linphone_core_set_sip_transports(lc,&tr); @@ -509,6 +514,8 @@ static void sip_config_read(LinphoneCore *lc) ms_free(contact); } + sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs")); + tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1); linphone_core_set_guess_hostname(lc,tmp); @@ -986,6 +993,7 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta linphone_core_assign_payload_type(&payload_type_mp4v,99,"profile-level-id=3"); linphone_core_assign_payload_type(&payload_type_x_snow,100,NULL); linphone_core_assign_payload_type(&payload_type_h264,102,"profile-level-id=428014"); + linphone_core_assign_payload_type(&payload_type_vp8,103,NULL); /* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */ /* linphone_core_assign_payload_type(&payload_type_h264,103,"packetization-mode=1;profile-level-id=428014");*/ #endif @@ -1359,7 +1367,7 @@ void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,bool_t use_rfc2833) int linphone_core_get_sip_port(LinphoneCore *lc) { LCSipTransports *tr=&lc->sip_conf.transports; - return tr->udp_port>0 ? tr->udp_port : tr->tcp_port; + return tr->udp_port>0 ? tr->udp_port : (tr->tcp_port > 0 ? tr->tcp_port : tr->tls_port); } static char _ua_name[64]="Linphone"; @@ -1420,13 +1428,18 @@ static int apply_transports(LinphoneCore *lc){ sal_unlisten_ports (sal); if (tr->udp_port>0){ if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportUDP,FALSE)!=0){ - transport_error(lc,"UDP",tr->udp_port); + transport_error(lc,"udp",tr->udp_port); return -1; } } if (tr->tcp_port>0){ if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportTCP,FALSE)!=0){ - transport_error(lc,"TCP",tr->tcp_port); + transport_error(lc,"tcp",tr->tcp_port); + } + } + if (tr->tls_port>0){ + if (sal_listen_port (sal,anyaddr,tr->tls_port,SalTransportTLS,TRUE)!=0){ + transport_error(lc,"tls",tr->tls_port); } } apply_user_agent(lc); @@ -2891,6 +2904,18 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){ return lc->sound_conf.local_ring; } +/** + * Sets the path to a file or folder containing trusted root CAs (PEM format) + * + * @param path + * @param lc The LinphoneCore object + * + * @ingroup media_parameters +**/ +void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){ + sal_root_ca(lc->sal, path); +} + static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){ LinphoneCore *lc=(LinphoneCore*)ud; lc->preview_finished=1; @@ -3755,6 +3780,7 @@ void sip_config_uninit(LinphoneCore *lc) sip_config_t *config=&lc->sip_conf; lp_config_set_int(lc->config,"sip","sip_port",config->transports.udp_port); lp_config_set_int(lc->config,"sip","sip_tcp_port",config->transports.tcp_port); + lp_config_set_int(lc->config,"sip","sip_tls_port",config->transports.tls_port); lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname); lp_config_set_string(lc->config,"sip","contact",config->contact); lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout); @@ -4219,4 +4245,9 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook ms_error("linphone_core_remove_iterate_hook(): No such hook found."); } - +void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ + if (lc->zrtp_secrets_cache != NULL) { + ms_free(lc->zrtp_secrets_cache); + } + lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 12bf72655..010b15851 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -527,6 +527,9 @@ const char *linphone_global_state_to_string(LinphoneGlobalState gs); typedef void (*LinphoneGlobalStateCb)(struct _LinphoneCore *lc, LinphoneGlobalState gstate, const char *message); /**Call state notification callback prototype*/ typedef void (*LinphoneCallStateCb)(struct _LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message); +/**Call encryption changed callback prototype*/ +typedef void (*CallEncryptionChangedCb)(struct _LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token); + /** @ingroup Proxies * Registration state notification callback prototype * */ @@ -600,6 +603,7 @@ typedef struct _LinphoneVTable{ DisplayMessageCb display_warning;/** Callback to display a warning to the user */ DisplayUrlCb display_url; ShowInterfaceCb show; /**< Notifies the application that it should show up*/ + CallEncryptionChangedCb call_encryption_changed; /** #include "linphonecore_utils.h" +#include #include "mediastreamer2/msjava.h" @@ -89,37 +90,47 @@ public: vTable.global_state_changed = globalStateChange; vTable.registration_state_changed = registrationStateChange; vTable.call_state_changed = callStateChange; + vTable.call_encryption_changed = callEncryptionChange; vTable.text_received = text_received; vTable.new_subscription_request = new_subscription_request; vTable.notify_presence_recv = notify_presence_recv; - listernerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); + listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener)); + /*displayStatus(LinphoneCore lc,String message);*/ - displayStatusId = env->GetMethodID(listernerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); + displayStatusId = env->GetMethodID(listenerClass,"displayStatus","(Lorg/linphone/core/LinphoneCore;Ljava/lang/String;)V"); + /*void generalState(LinphoneCore lc,int state); */ - globalStateId = env->GetMethodID(listernerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); + globalStateId = env->GetMethodID(listenerClass,"globalState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$GlobalState;Ljava/lang/String;)V"); globalStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$GlobalState")); globalStateFromIntId = env->GetStaticMethodID(globalStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$GlobalState;"); + /*registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage);*/ - registrationStateId = env->GetMethodID(listernerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); + registrationStateId = env->GetMethodID(listenerClass,"registrationState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneProxyConfig;Lorg/linphone/core/LinphoneCore$RegistrationState;Ljava/lang/String;)V"); registrationStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RegistrationState")); registrationStateFromIntId = env->GetStaticMethodID(registrationStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RegistrationState;"); + /*callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message);*/ - callStateId = env->GetMethodID(listernerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); + callStateId = env->GetMethodID(listenerClass,"callState","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;Lorg/linphone/core/LinphoneCall$State;Ljava/lang/String;)V"); callStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCall$State")); callStateFromIntId = env->GetStaticMethodID(callStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCall$State;"); + + /*callEncryption(LinphoneCore lc, LinphoneCall call, boolean encrypted,String auth_token);*/ + callEncryptionChangedId=env->GetMethodID(listenerClass,"callEncryptionChanged","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCall;ZLjava/lang/String;)V"); + /*void ecCalibrationStatus(LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data);*/ - ecCalibrationStatusId = env->GetMethodID(listernerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V"); + ecCalibrationStatusId = env->GetMethodID(listenerClass,"ecCalibrationStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;ILjava/lang/Object;)V"); ecCalibratorStatusClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$EcCalibratorStatus")); ecCalibratorStatusFromIntId = env->GetStaticMethodID(ecCalibratorStatusClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$EcCalibratorStatus;"); + /*void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url)*/ - newSubscriptionRequestId = env->GetMethodID(listernerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); + newSubscriptionRequestId = env->GetMethodID(listenerClass,"newSubscriptionRequest","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;Ljava/lang/String;)V"); /*void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf);*/ - notifyPresenceReceivedId = env->GetMethodID(listernerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); + notifyPresenceReceivedId = env->GetMethodID(listenerClass,"notifyPresenceReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneFriend;)V"); /*void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message);*/ - textReceivedId = env->GetMethodID(listernerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); + textReceivedId = env->GetMethodID(listenerClass,"textReceived","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatRoom;Lorg/linphone/core/LinphoneAddress;Ljava/lang/String;)V"); proxyClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl")); proxyCtrId = env->GetMethodID(proxyClass,"", "(J)V"); @@ -144,7 +155,7 @@ public: env->DeleteGlobalRef(core); env->DeleteGlobalRef(listener); if (userdata) env->DeleteGlobalRef(userdata); - env->DeleteGlobalRef(listernerClass); + env->DeleteGlobalRef(listenerClass); env->DeleteGlobalRef(globalStateClass); env->DeleteGlobalRef(registrationStateClass); env->DeleteGlobalRef(callStateClass); @@ -158,7 +169,7 @@ public: jobject listener; jobject userdata; - jclass listernerClass; + jclass listenerClass; jmethodID displayStatusId; jmethodID newSubscriptionRequestId; jmethodID notifyPresenceReceivedId; @@ -176,6 +187,8 @@ public: jmethodID callStateId; jmethodID callStateFromIntId; + jmethodID callEncryptionChangedId; + jclass ecCalibratorStatusClass; jmethodID ecCalibrationStatusId; jmethodID ecCalibratorStatusFromIntId; @@ -263,6 +276,21 @@ public: ,env->CallStaticObjectMethod(lcData->callStateClass,lcData->callStateFromIntId,(jint)state), message ? env->NewStringUTF(message) : NULL); } + static void callEncryptionChange(LinphoneCore *lc, LinphoneCall* call, bool_t encrypted,const char* authentication_token) { + JNIEnv *env = 0; + jint result = jvm->AttachCurrentThread(&env,NULL); + if (result != 0) { + ms_error("cannot attach VM\n"); + return; + } + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc); + env->CallVoidMethod(lcData->listener + ,lcData->callEncryptionChangedId + ,lcData->core + ,env->NewObject(lcData->callClass,lcData->callCtrId,(jlong)call) + ,encrypted + ,authentication_token ? env->NewStringUTF(authentication_token) : NULL); + } static void notify_presence_recv (LinphoneCore *lc, LinphoneFriend *my_friend) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); @@ -670,6 +698,14 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getRing(JNIEnv* env return NULL; } } +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setRootCA(JNIEnv* env + ,jobject thiz + ,jlong lc + ,jstring jpath) { + const char* path = jpath?env->GetStringUTFChars(jpath, NULL):NULL; + linphone_core_set_root_ca((LinphoneCore*)lc,path); + if (path) env->ReleaseStringUTFChars(jpath, path); +} extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableKeepAlive(JNIEnv* env ,jobject thiz ,jlong lc @@ -1268,6 +1304,9 @@ extern "C" jboolean Java_org_linphone_core_Version_nativeHasNeon(JNIEnv *env){ } return 0; } +extern "C" jboolean Java_org_linphone_core_Version_nativeHasZrtp(JNIEnv *env){ + return ortp_zrtp_available(); +} extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_pauseCall(JNIEnv *env,jobject thiz,jlong pCore, jlong pCall) { return linphone_core_pause_call((LinphoneCore *) pCore, (LinphoneCall *) pCall); @@ -1278,3 +1317,37 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_pauseAllCalls(JNIEnv *en extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_resumeCall(JNIEnv *env,jobject thiz,jlong pCore, jlong pCall) { return linphone_core_resume_call((LinphoneCore *) pCore, (LinphoneCall *) pCall); } + +extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setZrtpSecretsCache(JNIEnv *env,jobject thiz,jlong pCore, jstring jFile) { + if (jFile) { + const char* cFile=env->GetStringUTFChars(jFile, NULL); + linphone_core_set_zrtp_secrets_file((LinphoneCore *) pCore,cFile); + env->ReleaseStringUTFChars(jFile, cFile); + } else { + linphone_core_set_zrtp_secrets_file((LinphoneCore *) pCore,NULL); + } +} + +extern "C" jstring Java_org_linphone_core_LinphoneCallImpl_getAuthenticationToken(JNIEnv* env,jobject thiz,jlong ptr) { + LinphoneCall *call = (LinphoneCall *) ptr; + const char* token = linphone_call_get_authentication_token(call); + if (token == NULL) return NULL; + return env->NewStringUTF(token); +} +extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_isAuthenticationTokenVerified(JNIEnv* env,jobject thiz,jlong ptr) { + LinphoneCall *call = (LinphoneCall *) ptr; + return linphone_call_get_authentication_token_verified(call); +} +extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_areStreamsEncrypted(JNIEnv* env,jobject thiz,jlong ptr) { + return linphone_call_are_all_streams_encrypted((LinphoneCall *) ptr); +} + +// Needed by Galaxy S (can't switch to/from speaker while playing and still keep mic working) +// Implemented directly in msandroid.cpp (sound filters for Android). +extern "C" void msandroid_hack_speaker_state(bool speakerOn); + +extern "C" void Java_org_linphone_LinphoneManager_hackSpeakerState(JNIEnv* env,jobject thiz,jboolean speakerOn){ + msandroid_hack_speaker_state(speakerOn); +// End Galaxy S hack functions +} + diff --git a/coreapi/private.h b/coreapi/private.h index 4739c0c70..e79780b91 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -99,6 +99,12 @@ struct _LinphoneCall bool_t all_muted; /*this flag is set during early medias*/ bool_t playing_ringbacktone; bool_t owns_call_log; + OrtpEvQueue *audiostream_app_evq; + bool_t audiostream_encrypted; + char *auth_token; + bool_t auth_token_verified; + OrtpEvQueue *videostream_app_evq; + bool_t videostream_encrypted; }; @@ -440,6 +446,7 @@ struct _LinphoneCore bool_t network_reachable; bool_t use_preview_window; bool_t ringstream_autorelease; + char* zrtp_secrets_cache; }; bool_t linphone_core_can_we_add_call(LinphoneCore *lc); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index ff13f839e..dda1bc789 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -258,8 +258,12 @@ static char *guess_contact_for_register(LinphoneProxyConfig *obj){ linphone_address_set_display_name(contact,NULL); linphone_core_get_sip_transports(obj->lc,&tr); - if (tr.udp_port <= 0 && tr.tcp_port>0) { - sal_address_set_param(contact,"transport","TCP"); + if (tr.udp_port <= 0) { + if (tr.tcp_port>0) { + sal_address_set_param(contact,"transport","tcp"); + } else if (tr.tls_port>0) { + sal_address_set_param(contact,"transport","tls"); + } } ret=linphone_address_as_string(contact); linphone_address_destroy(contact); diff --git a/coreapi/sal.c b/coreapi/sal.c index b237e9ad9..e30e86be4 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -26,10 +26,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sal.h" const char* sal_transport_to_string(SalTransport transport) { switch (transport) { - case SalTransportUDP:return "UDP"; - case SalTransportTCP: return "TCP"; - case SalTransportTLS:return "TLS"; - case SalTransportDTLS:return "DTLS"; + case SalTransportUDP:return "udp"; + case SalTransportTCP: return "tcp"; + case SalTransportTLS:return "tls"; + case SalTransportDTLS:return "dtls"; default: { ms_fatal("Unexpected transport [%i]",transport); return NULL; @@ -38,10 +38,10 @@ const char* sal_transport_to_string(SalTransport transport) { } } SalTransport sal_transport_parse(const char* param) { - if (strcasecmp("UDP",param)==0) return SalTransportUDP; - if (strcasecmp("TCP",param)==0) return SalTransportTCP; - if (strcasecmp("TLS",param)==0) return SalTransportTLS; - if (strcasecmp("DTLS",param)==0) return SalTransportDTLS; + if (strcasecmp("udp",param)==0) return SalTransportUDP; + if (strcasecmp("tcp",param)==0) return SalTransportTCP; + if (strcasecmp("tls",param)==0) return SalTransportTLS; + if (strcasecmp("dtls",param)==0) return SalTransportDTLS; ms_error("Unkown transport type[%s], returning UDP", param); return SalTransportUDP; } diff --git a/coreapi/sal.h b/coreapi/sal.h index 47286b09c..01bf3c71a 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -276,6 +276,7 @@ void sal_reuse_authorization(Sal *ctx, bool_t enabled); void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec); void sal_use_rport(Sal *ctx, bool_t use_rports); void sal_use_101(Sal *ctx, bool_t use_101); +void sal_root_ca(Sal* ctx, const char* rootCa); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 7c04454b4..389179008 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -281,11 +281,14 @@ Sal * sal_init(){ sal->use_rports=TRUE; sal->use_101=TRUE; sal->reuse_authorization=FALSE; + sal->rootCa = 0; return sal; } void sal_uninit(Sal* sal){ eXosip_quit(); + if (sal->rootCa) + ms_free(sal->rootCa); ms_free(sal); } @@ -362,9 +365,17 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive); break; case SalTransportTCP: + case SalTransportTLS: proto= IPPROTO_TCP; keepalive=-1; - eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); + eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); + + if (ctx->rootCa) { + eXosip_tls_ctx_t tlsCtx; + memset(&tlsCtx, 0, sizeof(tlsCtx)); + snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa); + eXosip_set_tls_ctx(&tlsCtx); + } break; default: ms_warning("unexpected proto, using datagram"); @@ -382,11 +393,11 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i ipv6=strchr(addr,':')!=NULL; eXosip_enable_ipv6(ipv6); - if (is_secure){ - ms_fatal("SIP over TLS or DTLS is not supported yet."); + if (is_secure && tr == SalTransportUDP){ + ms_fatal("SIP over DTLS is not supported yet."); return -1; } - err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0); + err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure); #ifdef HAVE_EXOSIP_GET_SOCKET ms_message("Exosip has socket number %i",eXosip_get_socket(proto)); #endif @@ -431,6 +442,12 @@ void sal_use_101(Sal *ctx, bool_t use_101){ ctx->use_101=use_101; } +void sal_root_ca(Sal* ctx, const char* rootCa) { + if (ctx->rootCa) + ms_free(ctx->rootCa); + ctx->rootCa = ms_strdup(rootCa); +} + static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ osip_via_t *via=NULL; osip_generic_param_t *param=NULL; diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 201cb65a9..bdc257740 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -45,6 +45,7 @@ struct Sal{ bool_t use_rports; bool_t use_101; bool_t reuse_authorization; + char* rootCa; /* File _or_ folder containing root CA */ }; struct SalOp{ diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index e0f7cde34..a6edf1b7e 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -214,4 +214,9 @@ public interface LinphoneCall { * See getCurrentQuality() for more details about quality measurement. */ float getAverageQuality(); + + + String getAuthenticationToken(); + boolean isAuthenticationTokenVerified(); + boolean areStreamsEncrypted(); } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index 4afe7182f..91f056c23 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -528,6 +528,14 @@ public interface LinphoneCore { * @param null if not set */ String getRing(); + + /** + * Sets file or folder containing trusted root CAs + * + * @param path path to file with multiple PEM certif or to folder with multiple PEM files + */ + void setRootCA(String path); + void setUploadBandwidth(int bw); void setDownloadBandwidth(int bw); @@ -581,4 +589,7 @@ public interface LinphoneCore { boolean pauseCall(LinphoneCall call); boolean resumeCall(LinphoneCall call); boolean pauseAllCalls(); + + void setZrtpSecretsCache(String file); + } diff --git a/java/common/org/linphone/core/LinphoneCoreListener.java b/java/common/org/linphone/core/LinphoneCoreListener.java index ddd58a3ac..cfe43895e 100644 --- a/java/common/org/linphone/core/LinphoneCoreListener.java +++ b/java/common/org/linphone/core/LinphoneCoreListener.java @@ -15,7 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ + */ package org.linphone.core; @@ -27,65 +27,81 @@ public interface LinphoneCoreListener { /**< Notifies the application that it should show up * @return */ - public void show(LinphoneCore lc); - /**< Ask the application some authentication information - * @return */ - public void authInfoRequested(LinphoneCore lc,String realm,String username); - /**< Callback that notifies various events with human readable text. - * @return */ - public void displayStatus(LinphoneCore lc,String message); - /**< Callback to display a message to the user - * @return */ - public void displayMessage(LinphoneCore lc,String message); - /** Callback to display a warning to the user - * @return */ - public void displayWarning(LinphoneCore lc,String message); - /** General State notification - * @param state LinphoneCore.State - * @return - * */ - public void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message); - /** Call State notification - * @param state LinphoneCall.State - * @return - * */ - - public void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message); - /** - * Registration state notification - * */ - public void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage); - /** - * Reports that a new subscription request has been received and wait for a decision. - *Status on this subscription request is notified by changing policy for this friend - *@param lc LinphoneCore - *@param lf LinphoneFriend corresponding to the subscriber - *@param url of the subscriber - * - */ - public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url); - /** - * Report status change for a friend previously added to LinphoneCore. - * @param lc LinphoneCore - * @param lf updated LinphoneFriend - */ - public void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf); - /** - * invoked when a new text message is received - * @param lc LinphoneCore - * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. - * @param from LinphoneAddress from - * @param message incoming message - */ - public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message); - /** - * Invoked when echo cancalation calibration is completed - * @param lc LinphoneCore - * @param status - * @param delay_ms echo delay - * @param data - */ - void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data); - + void show(LinphoneCore lc); + + /**< Ask the application some authentication information + * @return */ + void authInfoRequested(LinphoneCore lc,String realm,String username); + + /**< Callback that notifies various events with human readable text. + * @return */ + void displayStatus(LinphoneCore lc,String message); + + /**< Callback to display a message to the user + * @return */ + void displayMessage(LinphoneCore lc,String message); + + /** Callback to display a warning to the user + * @return */ + void displayWarning(LinphoneCore lc,String message); + + /** General State notification + * @param state LinphoneCore.State + * @return + * */ + void globalState(LinphoneCore lc,LinphoneCore.GlobalState state, String message); + + /** Call State notification + * @param state LinphoneCall.State + * @return + * */ + void callState(LinphoneCore lc, LinphoneCall call, LinphoneCall.State cstate,String message); + + /** + * Callback to display change in encryption state. + * @param encrypted true if all streams of the call are encrypted + * @param authenticationToken token like ZRTP SAS that may be displayed to user + */ + void callEncryptionChanged(LinphoneCore lc, LinphoneCall call, boolean encrypted, String authenticationToken); + + /** + * Registration state notification + * */ + void registrationState(LinphoneCore lc, LinphoneProxyConfig cfg, LinphoneCore.RegistrationState cstate, String smessage); + + /** + * Reports that a new subscription request has been received and wait for a decision. + *Status on this subscription request is notified by changing policy for this friend + *@param lc LinphoneCore + *@param lf LinphoneFriend corresponding to the subscriber + *@param url of the subscriber + * + */ + void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf, String url); + + /** + * Report status change for a friend previously added to LinphoneCore. + * @param lc LinphoneCore + * @param lf updated LinphoneFriend + */ + void notifyPresenceReceived(LinphoneCore lc, LinphoneFriend lf); + + /** + * invoked when a new text message is received + * @param lc LinphoneCore + * @param room LinphoneChatRoom involved in this conversation. Can be be created by the framework in case the from is not present in any chat room. + * @param from LinphoneAddress from + * @param message incoming message + */ + void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from,String message); + + /** + * Invoked when echo cancalation calibration is completed + * @param lc LinphoneCore + * @param status + * @param delay_ms echo delay + * @param data + */ + void ecCalibrationStatus(LinphoneCore lc,LinphoneCore.EcCalibratorStatus status, int delay_ms, Object data); } diff --git a/m4/exosip.m4 b/m4/exosip.m4 index cf1db587d..2c21b129d 100644 --- a/m4/exosip.m4 +++ b/m4/exosip.m4 @@ -25,9 +25,9 @@ dnl check for eXosip2 libs LDFLAGS_save=$LDFLAGS LDFLAGS="$OSIP_LIBS $LDFLAGS $OPENSSL_LIBS" LIBS_save=$LIBS -AC_CHECK_LIB([eXosip2],[eXosip_subscribe_remove], +AC_CHECK_LIB([eXosip2],[eXosip_set_tls_ctx], [], - [AC_MSG_ERROR([Could not find eXosip2 library with version >= 3.0.2 !])], + [AC_MSG_ERROR([Could not find eXosip2 library with version >= 3.5.0 !])], [-losipparser2 -losip2 ]) AC_CHECK_LIB([eXosip2],[eXosip_get_version], [AC_DEFINE([HAVE_EXOSIP_GET_VERSION],[1],[Defined when eXosip_get_version is available])], diff --git a/mediastreamer2 b/mediastreamer2 index 187a2132c..e29762297 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 187a2132cebc630086384bfa8c7a9a50b260cbaf +Subproject commit e297622976e5dcae7ec9de1233178149d30b42ad diff --git a/oRTP b/oRTP index 662a65869..536ad766c 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 662a65869902a927673d9ceff10781e217ca8e9d +Subproject commit 536ad766cf13da4115c456170afee96113de533f