diff --git a/coreapi/authentication.c b/coreapi/authentication.c index ee360ecfe..618504884 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -55,6 +55,18 @@ LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *useri return obj; } +static LinphoneAuthInfo *linphone_auth_info_clone(const LinphoneAuthInfo *ai){ + LinphoneAuthInfo *obj=ms_new0(LinphoneAuthInfo,1); + if (ai->username) obj->username=ms_strdup(ai->username); + if (ai->userid) obj->userid=ms_strdup(ai->userid); + if (ai->passwd) obj->passwd=ms_strdup(ai->passwd); + if (ai->ha1) obj->ha1=ms_strdup(ai->ha1); + if (ai->realm) obj->realm=ms_strdup(ai->realm); + obj->works=FALSE; + obj->first_time=TRUE; + return obj; +} + /** * Sets the password. **/ @@ -180,7 +192,7 @@ static int realm_match(const char *realm1, const char *realm2){ /** * Retrieves a LinphoneAuthInfo previously entered into the LinphoneCore. **/ -LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username) +const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username) { MSList *elem; LinphoneAuthInfo *ret=NULL,*candidate=NULL; @@ -232,24 +244,18 @@ static void refresh_exosip_auth_info(LinphoneCore *lc){ * * This information will be used during all SIP transacations that require authentication. **/ -void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info) +void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info) { - MSList *elem; LinphoneAuthInfo *ai; /* find if we are attempting to modify an existing auth info */ - ai=linphone_core_find_auth_info(lc,info->realm,info->username); + ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username); if (ai!=NULL){ - elem=ms_list_find(lc->auth_info,ai); - if (elem==NULL){ - ms_error("AuthInfo list corruption ?"); - return; - } - linphone_auth_info_destroy((LinphoneAuthInfo*)elem->data); - elem->data=(void *)info; - }else { - lc->auth_info=ms_list_append(lc->auth_info,(void *)info); + lc->auth_info=ms_list_remove(lc->auth_info,ai); + linphone_auth_info_destroy(ai); } + lc->auth_info=ms_list_append(lc->auth_info,linphone_auth_info_clone(info)); + refresh_exosip_auth_info(lc); /* if the user was prompted, re-allow automatic_action */ if (lc->automatic_action>0) lc->automatic_action--; @@ -267,23 +273,21 @@ void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *inf /** * Removes an authentication information object. **/ -void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info){ - int len=ms_list_size(lc->auth_info); - int newlen; +void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){ int i; MSList *elem; - lc->auth_info=ms_list_remove(lc->auth_info,info); - newlen=ms_list_size(lc->auth_info); - /*printf("len=%i newlen=%i\n",len,newlen);*/ - linphone_auth_info_destroy(info); - for (i=0;irealm,info->username); + if (r){ + lc->auth_info=ms_list_remove(lc->auth_info,r); + /*printf("len=%i newlen=%i\n",len,newlen);*/ + linphone_auth_info_destroy(r); + for (elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ + linphone_auth_info_write_config(lc->config,(LinphoneAuthInfo*)elem->data,i); + } linphone_auth_info_write_config(lc->config,NULL,i); + refresh_exosip_auth_info(lc); } - for (elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){ - linphone_auth_info_write_config(lc->config,(LinphoneAuthInfo*)elem->data,i); - } - refresh_exosip_auth_info(lc); - } /** @@ -333,9 +337,9 @@ void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev){ } /* see if we already have this auth information , not to ask it everytime to the user */ if (prx_realm!=NULL) - as=linphone_core_find_auth_info(lc,prx_realm,username); + as=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,prx_realm,username); if (www_realm!=NULL) - as=linphone_core_find_auth_info(lc,www_realm,username); + as=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,www_realm,username); if (as){ ms_message("Authentication for user=%s realm=%s is working.",username,prx_realm ? prx_realm : www_realm); as->works=TRUE; @@ -345,7 +349,7 @@ void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev){ void linphone_core_find_or_ask_for_auth_info(LinphoneCore *lc,const char *username,const char* realm, int tid) { - LinphoneAuthInfo *as=linphone_core_find_auth_info(lc,realm,username); + LinphoneAuthInfo *as=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username); if ( as==NULL || (as!=NULL && as->works==FALSE && as->first_time==FALSE)){ if (lc->vtable.auth_info_requested!=NULL){ lc->vtable.auth_info_requested(lc,realm,username); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3c46d92a0..d54b4907e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -720,7 +720,7 @@ static void codecs_config_read(LinphoneCore *lc) static void video_config_read(LinphoneCore *lc) { - int capture, display; + int capture, display, self_view; int enabled; const char *str; int ndev; @@ -748,9 +748,10 @@ static void video_config_read(LinphoneCore *lc) enabled=lp_config_get_int(lc->config,"video","enabled",1); capture=lp_config_get_int(lc->config,"video","capture",enabled); display=lp_config_get_int(lc->config,"video","display",enabled); + self_view=lp_config_get_int(lc->config,"video","self_view",enabled); #ifdef VIDEO_ENABLED linphone_core_enable_video(lc,capture,display); - linphone_core_enable_self_view(lc,TRUE); + linphone_core_enable_self_view(lc,self_view); #endif } @@ -2986,11 +2987,6 @@ void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t di lc->video_conf.capture=vcap_enabled; lc->video_conf.display=display_enabled; - if (lc->ready){ - lp_config_set_int(lc->config,"video","display",display_enabled); - lp_config_set_int(lc->config,"video","capture",vcap_enabled); - } - /* need to re-apply network bandwidth settings*/ linphone_core_set_download_bandwidth(lc, linphone_core_get_download_bandwidth(lc)); @@ -3015,7 +3011,6 @@ bool_t linphone_core_video_enabled(LinphoneCore *lc){ **/ void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val){ lc->video_conf.show_local=val; - if (lc->ready) lp_config_set_int(lc->config,"video","show_local",val); } /** @@ -3356,7 +3351,7 @@ void rtp_config_uninit(LinphoneCore *lc) lp_config_set_int(lc->config,"rtp","audio_rtp_port",config->audio_rtp_port); lp_config_set_int(lc->config,"rtp","video_rtp_port",config->video_rtp_port); lp_config_set_int(lc->config,"rtp","audio_jitt_comp",config->audio_jitt_comp); - lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->audio_jitt_comp); + lp_config_set_int(lc->config,"rtp","video_jitt_comp",config->video_jitt_comp); lp_config_set_int(lc->config,"rtp","nortp_timeout",config->nortp_timeout); } @@ -3374,7 +3369,12 @@ void sound_config_uninit(LinphoneCore *lc) void video_config_uninit(LinphoneCore *lc) { - + lp_config_set_int(lc->config,"video","enabled",linphone_core_video_enabled(lc)); + lp_config_set_string(lc->config,"video","size",video_size_get_name(linphone_core_get_preferred_video_size(lc))); + lp_config_set_int(lc->config,"video","display",lc->video_conf.display); + lp_config_set_int(lc->config,"video","capture",lc->video_conf.capture); + lp_config_set_int(lc->config,"video","show_local",linphone_core_video_preview_enabled(lc)); + lp_config_set_int(lc->config,"video","self_view",linphone_core_self_view_enabled(lc)); } void codecs_config_uninit(LinphoneCore *lc) @@ -3462,6 +3462,7 @@ static void linphone_core_uninit(LinphoneCore *lc) ui_config_uninit(lc); if (lp_config_needs_commit(lc->config)) lp_config_sync(lc->config); lp_config_destroy(lc->config); + lc->config = NULL; /* Mark the config as NULL to block further calls */ sip_setup_unregister_all(); linphone_core_free_payload_types(); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index e592089dd..9ce867053 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -43,10 +43,6 @@ struct _LinphoneCore; bool_t payload_type_enabled(struct _PayloadType *pt); void payload_type_set_enable(struct _PayloadType *pt,int value); const char *payload_type_get_description(struct _PayloadType *pt); -int payload_type_get_bitrate(PayloadType *pt); -const char *payload_type_get_mime(PayloadType *pt); -int payload_type_get_rate(PayloadType *pt); - struct _LpConfig; @@ -746,13 +742,13 @@ void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index); int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config); -void linphone_core_add_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info); +void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info); -void linphone_core_remove_auth_info(LinphoneCore *lc, LinphoneAuthInfo *info); +void linphone_core_remove_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info); const MSList *linphone_core_get_auth_info_list(const LinphoneCore *lc); -LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username); +const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username); void linphone_core_abort_authentication(LinphoneCore *lc, LinphoneAuthInfo *info); diff --git a/coreapi/misc.c b/coreapi/misc.c index c2ba26297..db2c93932 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -185,18 +185,6 @@ bool_t payload_type_enabled(PayloadType *pt) { return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0); } -int payload_type_get_bitrate(PayloadType *pt) -{ - return pt->normal_bitrate; -} -const char *payload_type_get_mime(PayloadType *pt){ - return pt->mime_type; -} - -int payload_type_get_rate(PayloadType *pt){ - return pt->clock_rate; -} - /*this function makes a special case for speex/8000. This codec is variable bitrate. The 8kbit/s mode is interesting when having a low upload bandwidth, but its quality is not very good. We 'd better use its 15kbt/s mode when we have enough bandwidth*/ diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 437c85e60..4a9720a35 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -792,9 +792,9 @@ void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, int LinphoneAuthInfo *as=NULL; /* see if we already have this auth information , not to ask it everytime to the user */ if (prx_realm!=NULL) - as=linphone_core_find_auth_info(lc,prx_realm,username); + as=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,prx_realm,username); if (www_realm!=NULL) - as=linphone_core_find_auth_info(lc,www_realm,username); + as=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,www_realm,username); if (as) as->first_time=TRUE; } diff --git a/gtk-glade/logging.c b/gtk-glade/logging.c index a8211d1ea..856937349 100644 --- a/gtk-glade/logging.c +++ b/gtk-glade/logging.c @@ -19,6 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" +#ifndef WIN32 +#include +#include +#endif + + static GtkWidget *log_window=NULL; static GStaticMutex log_mutex=G_STATIC_MUTEX_INIT; static GList *log_queue=NULL; @@ -28,6 +34,186 @@ typedef struct _LinphoneGtkLog{ gchar *msg; }LinphoneGtkLog; + +/****** + * Module to log to a file + ******/ + +/* Marker to insert as a line at the start of every log file */ +#define LOGFILE_MARKER_START "--------" +/* Marker to insert as a line at the end of every log file */ +#define LOGFILE_MARKER_STOP "--------" +/* Number of files to keep in history, log file rotation will be + performed. */ +#define LOGFILE_ROTATION 4 +/* Pointer to opened log file */ +static FILE *_logfile = NULL; + + +/* Called on exit, print out the marker, close the file and avoid to + continue logging. */ +static void linphone_gtk_log_uninit() +{ + if (_logfile != NULL) { + fprintf(_logfile, "%s\n", LOGFILE_MARKER_STOP); + fclose(_logfile); + _logfile = NULL; + } +} + +/* Called when we start logging, find a good place for the log files, + perform rotation, insert the start marker and return the pointer to + the file that should be used for logging, or NULL on errors or if + disabled. */ +static FILE *linphone_gtk_log_init() +{ + static char _logdir[1024]; + static char _logfname[1024]; + static gboolean _log_init = FALSE; + const char *dst_fname; + + dst_fname = linphone_gtk_get_ui_config("logfile",NULL); + /* For anything to happen, we need a logfile configuration variable, + this is our trigger */ + if (dst_fname) { + /* If we haven't initialised yet, arrange for _logdir to contain a + directory that has been created and _logfname to contain the + path to a file to which we will log */ + if (!_log_init) { +#ifdef WIN32 + const char *appdata=getenv("LOCALAPPDATA"); + if (appdata) { + snprintf(_logdir, sizeof(_logdir),"%s\\Linphone", appdata); + mkdir(_logdir); + } else { + _logdir[0] = '\0'; + } +#define PATH_SEPARATOR '\\' +#else + const char *home=getenv("HOME"); + if (home) { + snprintf(_logdir, sizeof(_logdir),"%s/.linphone", home); + mkdir(_logdir,S_IRUSR | S_IWUSR | S_IRGRP); + } else { + _logdir[0] = '\0'; + } +#define PATH_SEPARATOR '/' +#endif + /* We have a directory, fix the path to the log file in it and + open the file so that we will be appending to it. */ + if (_logdir[0] != '\0') { + snprintf(_logfname, sizeof(_logfname), "%s%c%s", + _logdir, PATH_SEPARATOR, dst_fname); + /* If the constant LOGFILE_ROTATION is greater than zero, then + we kick away a simple rotation that will ensure that there + are never more than LOGFILE_ROTATION+1 old copies of the + log file on the disk. The oldest file is always rotated + "away" as expected. Rotated files have the same name as + the main log file, though with a number 0..LOGFILE_ROTATION + at the end, where the greater the number is, the older the + file is. */ + if (ortp_file_exist(_logfname)==0 && LOGFILE_ROTATION > 0) { + int i; + char old_fname[1024]; + char new_fname[1024]; + + /* Rotate away existing files. We make sure to remove the + old files otherwise rename() would not work properly. We + have to loop in reverse here. */ + for (i=LOGFILE_ROTATION-1;i>=0;i--) { + snprintf(old_fname, sizeof(old_fname), "%s%c%s.%d", + _logdir, PATH_SEPARATOR, dst_fname, i); + snprintf(new_fname, sizeof(new_fname), "%s%c%s.%d", + _logdir, PATH_SEPARATOR, dst_fname, i+1); + if (ortp_file_exist(old_fname)==0) { + if (ortp_file_exist(new_fname)==0) + unlink(new_fname); + rename(old_fname, new_fname); + } + } + /* Move current log file as the first of the rotation. Make + sure to remove the old .0 also, since otherwise rename() + would not work as expected. */ + snprintf(new_fname, sizeof(new_fname), "%s%c%s.%d", + _logdir, PATH_SEPARATOR, dst_fname, 0); + if (ortp_file_exist(new_fname)==0) + unlink(new_fname); + rename(_logfname, new_fname); + } + /* Start a new log file and mark that we have now initialised */ + _logfile = fopen(_logfname, "w"); + fprintf(_logfile, "%s\n", LOGFILE_MARKER_START); + _log_init = TRUE; + } + } + } + + return _logfile; +} + +static void linphone_gtk_log_file(OrtpLogLevel lev, const char *msg) +{ + LinphoneCore *lc; + time_t now; + FILE *outlog; + + lc = linphone_gtk_get_core(); + /* Nothing to do until the core has initialised */ + if (lc == NULL) + return; + + /* lc->config will turn NULL at exit, close the file to flush and + return to stop logging */ + if (lc->config == NULL) { + linphone_gtk_log_uninit(); + return; + } + + outlog = linphone_gtk_log_init(); + if (outlog != NULL) { + /* We have an opened file and we have initialised properly, it's + time to write all these log messages. We convert the log level + from oRTP into something readable and timestamp each log + message. The format of the timestamp can be controlled by + logfile_date_format in the GtkUi section of the config file, + but it defaults to something compact, but yet readable. */ + const char *lname="undef"; + const char *dateformat=linphone_gtk_get_ui_config("logfile_date_format", + "%Y%m%d-%H:%M:%S"); + char date[256]; + + /* Convert level constant to text */ + switch(lev){ + case ORTP_DEBUG: + lname="debug"; + break; + case ORTP_MESSAGE: + lname="message"; + break; + case ORTP_WARNING: + lname="warning"; + break; + case ORTP_ERROR: + lname="error"; + break; + case ORTP_FATAL: + lname="fatal"; + break; + default: + lname="undef"; + break; + } + /* Get current time and format it properly */ + now = time(NULL); + strftime(date, sizeof(date), dateformat, localtime(&now)); + /* Now print out the message to the logfile. We don't flush, + maybe we should do to ensure that we have all the messages in + case of a crash (which is one of the main reasons we have a + log facility in the first place). */ + fprintf(outlog, "[%s] [%s] %s\n", date, lname, msg); + } +} + void linphone_gtk_create_log_window(void){ GtkTextBuffer *b; log_window=linphone_gtk_create_window("log"); @@ -120,6 +306,7 @@ void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args){ lgl->msg=msg; g_static_mutex_lock(&log_mutex); log_queue=g_list_append(log_queue,lgl); + linphone_gtk_log_file(lev, msg); g_static_mutex_unlock(&log_mutex); } diff --git a/gtk-glade/loginframe.c b/gtk-glade/loginframe.c index d4ed36974..c6f310b4e 100644 --- a/gtk-glade/loginframe.c +++ b/gtk-glade/loginframe.c @@ -55,7 +55,7 @@ static gboolean do_login_noprompt(LinphoneProxyConfig *cfg){ void linphone_gtk_show_login_frame(LinphoneProxyConfig *cfg){ GtkWidget *mw=linphone_gtk_get_main_window(); GtkWidget *label=linphone_gtk_get_widget(mw,"login_label"); - LinphoneAuthInfo *ai; + const LinphoneAuthInfo *ai; gchar *str; LinphoneAddress *from; LinphoneCore *lc=linphone_gtk_get_core(); diff --git a/gtk-glade/main.c b/gtk-glade/main.c index e6e2ac79a..579c3e34a 100644 --- a/gtk-glade/main.c +++ b/gtk-glade/main.c @@ -369,21 +369,37 @@ static void set_video_window_decorations(GdkWindow *w){ char video_title[256]; GdkPixbuf *pbuf=create_pixbuf(icon_path); if (!linphone_core_in_call(linphone_gtk_get_core())){ - snprintf(video_title,sizeof(video_title),"%s video",title); + snprintf(video_title,sizeof(video_title),"%s video",title); + /* When not in call, treat the video as a normal window */ + gdk_window_set_keep_above(w, FALSE); }else{ - const LinphoneAddress *uri=linphone_core_get_remote_uri(linphone_gtk_get_core()); + LinphoneAddress *uri = + linphone_address_clone(linphone_core_get_remote_uri(linphone_gtk_get_core())); char *display_name; - if (linphone_address_get_display_name(uri)!=NULL) + + linphone_address_clean(uri); + if (linphone_address_get_display_name(uri)!=NULL){ display_name=ms_strdup(linphone_address_get_display_name(uri)); - else{ + }else{ display_name=linphone_address_as_string(uri); } snprintf(video_title,sizeof(video_title),_("Call with %s"),display_name); + linphone_address_destroy(uri); ms_free(display_name); + + /* During calls, bring up the video window, arrange so that + it is above all the other windows */ + gdk_window_deiconify(w); + gdk_window_set_keep_above(w,TRUE); + /* Maybe we should have the following, but then we want to + have a timer that turns it off after a little while. */ + /* gdk_window_set_urgency_hint(w,TRUE); */ } gdk_window_set_title(w,video_title); - /*gdk_window_set_urgency_hint(w,TRUE);*/ - gdk_window_raise(w); + /* Refrain the video window to be closed at all times. */ + gdk_window_set_functions(w, + GDK_FUNC_RESIZE|GDK_FUNC_MOVE| + GDK_FUNC_MINIMIZE|GDK_FUNC_MAXIMIZE); if (pbuf){ GList *l=NULL; l=g_list_append(l,pbuf); diff --git a/mediastreamer2 b/mediastreamer2 index 637302226..ae7dfdcae 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 6373022261b4a529400a0c0e1661b4d3e5ebc7c5 +Subproject commit ae7dfdcaea6d5fe6d4f44a6247b4ca506799e379 diff --git a/oRTP b/oRTP index 7283d8357..36773054c 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 7283d835734d07773ea9e37f89215c123322b48d +Subproject commit 36773054c1e9a47029432a2e8540161dad426293