From 75eee41a760d688a05ed625c7406b56d2845f669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Tue, 9 Sep 2014 12:25:29 +0200 Subject: [PATCH] Fix bug #1426: Echo cancelation state blob is too big for being in linphonerc The state of the echo canceler is stored in a file beside .linphonerc The file is named .linphone.ecstate --- coreapi/linphonecall.c | 7 +++-- coreapi/lpconfig.c | 58 ++++++++++++++++++++++++++++++++++++++++++ coreapi/lpconfig.h | 16 ++++++++++++ 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 578313794..9c33bd27a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -37,6 +37,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mseventqueue.h" #include "mediastreamer2/mssndcard.h" +static const char EC_STATE_STORE[] = ".linphone.ecstate"; + static void linphone_call_stats_uninit(LinphoneCallStats *stats); #ifdef VIDEO_ENABLED @@ -1544,13 +1546,14 @@ void linphone_call_init_audio_stream(LinphoneCall *call){ audio_stream_enable_gain_control(audiostream,TRUE); if (linphone_core_echo_cancellation_enabled(lc)){ int len,delay,framesize; - const char *statestr=lp_config_get_string(lc->config,"sound","ec_state",NULL); + char *statestr=lp_config_read_relative_file(lc->config, EC_STATE_STORE); len=lp_config_get_int(lc->config,"sound","ec_tail_len",0); delay=lp_config_get_int(lc->config,"sound","ec_delay",0); framesize=lp_config_get_int(lc->config,"sound","ec_framesize",0); audio_stream_set_echo_canceller_params(audiostream,len,delay,framesize); if (statestr && audiostream->ec){ ms_filter_call_method(audiostream->ec,MS_ECHO_CANCELLER_SET_STATE_STRING,(void*)statestr); + ms_free(statestr); } } audio_stream_enable_automatic_gain_control(audiostream,linphone_core_agc_enabled(lc)); @@ -2286,7 +2289,7 @@ static void linphone_call_stop_audio_stream(LinphoneCall *call) { ms_filter_call_method(call->audiostream->ec,MS_ECHO_CANCELLER_GET_STATE_STRING,&state_str); if (state_str){ ms_message("Writing echo canceler state, %i bytes",(int)strlen(state_str)); - lp_config_set_string(call->core->config,"sound","ec_state",state_str); + lp_config_write_relative_file(call->core->config, EC_STATE_STORE, state_str); } } audio_stream_get_local_rtp_stats(call->audiostream,&call->log->local_stats); diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index 680198cd3..ed33d809d 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -39,6 +39,12 @@ #endif #endif /*_WIN32_WCE*/ +#ifdef WIN32 +#include +#else +#include +#endif + #define lp_new0(type,n) (type*)calloc(sizeof(type),n) @@ -657,3 +663,55 @@ const char* lp_config_get_default_string(const LpConfig *lpconfig, const char *s return lp_config_get_string(lpconfig, default_section, key, default_value); } + +static char *_lp_config_dirname(char *path) { +#ifdef WIN32 + char *dir = ms_strdup(path); + PathRemoveFileSpec(dir); + return dir; +#else + char *tmp = ms_strdup(path); + char *dir = ms_strdup(dirname(tmp)); + ms_free(tmp); + return dir; +#endif +} + +void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) { + if(strlen(data) > 0) { + char *dir = _lp_config_dirname(lpconfig->filename); + char *filepath = ms_strdup_printf("%s/%s", dir, filename); + FILE *file = fopen(filepath, "w"); + if(file != NULL) { + fprintf(file, "%s", data); + fclose(file); + } else { + ms_error("Could not open %s for write", filepath); + } + ms_free(dir); + ms_free(filepath); + } else { + ms_warning("%s has not been created because there is no data to write", filename); + } +} + +char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename) { + char *dir = _lp_config_dirname(lpconfig->filename); + char *filepath = ms_strdup_printf("%s/%s", dir, filename); + char *result = NULL; + if(access(filepath, F_OK) == 0) { + FILE *file = fopen(filepath, "r"); + if(file != NULL) { + result = ms_new0(char, MAX_LEN); + fgets(result, MAX_LEN, file); + fclose(file); + } else { + ms_error("Could not open %s for read", filepath); + } + } else { + ms_message("%s does not exist", filepath); + } + ms_free(dir); + ms_free(filepath); + return result; +} diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h index bd229803e..3498f00d2 100644 --- a/coreapi/lpconfig.h +++ b/coreapi/lpconfig.h @@ -272,6 +272,22 @@ LINPHONE_PUBLIC LpConfig *lp_config_ref(LpConfig *lpconfig); **/ LINPHONE_PUBLIC void lp_config_unref(LpConfig *lpconfig); +/** + * @brief Write a string in a file placed relatively with the Linphone configuration file. + * @param lpconfig LpConfig instance used as a reference + * @param filename Name of the file where to write data. The name is relative to the place of the config file + * @param data String to write + */ +LINPHONE_PUBLIC void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data); + +/** + * @brief Read a string from a file placed relatively with the Linphone configuration file + * @param lpconfig LpConfig instance used as a reference + * @param filename Name of the file where data will be read from. The name is relative to the place of the config file + * @return The read string + */ +LINPHONE_PUBLIC char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename); + #ifdef __cplusplus } #endif