From 130d4710287df46b36248200c21517dec6a67b1b Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 23 Mar 2017 11:55:39 +0100 Subject: [PATCH 01/11] fix crash and memory leaks --- coreapi/error_info.c | 29 +++++----- coreapi/factory.c | 107 +++++++++++++++++++++++++------------ coreapi/linphonecore.c | 9 ++-- coreapi/private.h | 7 ++- gtk/main.c | 12 ++--- gtk/support.c | 3 +- include/linphone/factory.h | 12 ++--- mediastreamer2 | 2 +- tools/auto_answer.c | 3 +- 9 files changed, 106 insertions(+), 78 deletions(-) diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 288b8e793..3add603a9 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -22,22 +22,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneErrorInfo); -#define STRING_RESET(field) if (field) ms_free(field); field = NULL; +static void linphone_error_info_reset(LinphoneErrorInfo *ei); static void error_info_destroy(LinphoneErrorInfo *ei){ - if (ei->protocol) ms_free(ei->protocol); - if (ei->phrase) ms_free(ei->phrase); - if (ei->warnings) ms_free(ei->phrase); - if (ei->full_string) ms_free(ei->full_string); + linphone_error_info_reset(ei); } static void error_info_clone(LinphoneErrorInfo *ei, const LinphoneErrorInfo *other){ - ei->protocol = ms_strdup_safe(other->protocol); - ei->phrase = ms_strdup_safe(other->phrase); - ei->warnings = ms_strdup_safe(other->phrase); - ei->full_string = ms_strdup_safe(other->full_string); + ei->protocol = bctbx_strdup(other->protocol); + ei->phrase = bctbx_strdup(other->phrase); + ei->warnings = bctbx_strdup(other->warnings); + ei->full_string = bctbx_strdup(other->full_string); } BELLE_SIP_INSTANCIATE_VPTR(LinphoneErrorInfo, belle_sip_object_t, @@ -155,7 +152,7 @@ int linphone_reason_to_error_code(LinphoneReason reason) { return 400; } -void linphone_error_info_reset(LinphoneErrorInfo *ei){ +static void linphone_error_info_reset(LinphoneErrorInfo *ei){ ei->reason = LinphoneReasonNone; STRING_RESET(ei->protocol); STRING_RESET(ei->phrase); @@ -170,11 +167,11 @@ void linphone_error_info_reset(LinphoneErrorInfo *ei){ void linphone_error_info_from_sal(LinphoneErrorInfo *ei, const SalErrorInfo *sei){ ei->reason = linphone_reason_from_sal(sei->reason); - ei->phrase = ms_strdup_safe(sei->status_string); - ei->full_string = ms_strdup_safe(sei->full_string); - ei->warnings = ms_strdup_safe(sei->warnings); + ei->phrase = bctbx_strdup(sei->status_string); + ei->full_string = bctbx_strdup(sei->full_string); + ei->warnings = bctbx_strdup(sei->warnings); ei->protocol_code = sei->protocol_code; - ei->protocol = ms_strdup_safe(sei->protocol); + ei->protocol = bctbx_strdup(sei->protocol); } /* If a reason header is provided (in reason_ei), then create a sub LinphoneErrorInfo attached to the first one, unless the reason header @@ -220,8 +217,8 @@ void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int c linphone_error_info_reset(ei); ei->reason = reason; ei->protocol_code = code; - ei->phrase = ms_strdup_safe(status_string); - ei->warnings = ms_strdup_safe(warning); + ei->phrase = bctbx_strdup(status_string); + ei->warnings = bctbx_strdup(warning); } diff --git a/coreapi/factory.c b/coreapi/factory.c index 867d6be24..b43bd0136 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -39,17 +39,40 @@ typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t; struct _LinphoneFactory { belle_sip_object_t base; + /*these are the directories set by the application*/ char *top_resources_dir; char *data_resources_dir; char *sound_resources_dir; char *ring_resources_dir; char *image_resources_dir; char *msplugins_dir; + + /*these are the cached result computed from directories set by the application*/ + char *cached_data_resources_dir; + char *cached_sound_resources_dir; + char *cached_ring_resources_dir; + char *cached_image_resources_dir; + char *cached_msplugins_dir; }; +static void linphone_factory_uninit(LinphoneFactory *obj){ + STRING_RESET(obj->top_resources_dir); + STRING_RESET(obj->data_resources_dir); + STRING_RESET(obj->sound_resources_dir); + STRING_RESET(obj->ring_resources_dir); + STRING_RESET(obj->image_resources_dir); + STRING_RESET(obj->msplugins_dir); + + STRING_RESET(obj->cached_data_resources_dir); + STRING_RESET(obj->cached_sound_resources_dir); + STRING_RESET(obj->cached_ring_resources_dir); + STRING_RESET(obj->cached_image_resources_dir); + STRING_RESET(obj->cached_msplugins_dir); +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFactory); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFactory, belle_sip_object_t, - NULL, // destroy + linphone_factory_uninit, // destroy NULL, // clone NULL, // Marshall FALSE @@ -64,9 +87,16 @@ static void _linphone_factory_destroying_cb(void) { } } +static LinphoneFactory *linphone_factory_new(void){ + LinphoneFactory *factory = belle_sip_object_new(LinphoneFactory); + factory->top_resources_dir = bctbx_strdup(PACKAGE_DATA_DIR); + return factory; +} + + LinphoneFactory *linphone_factory_get(void) { if (_factory == NULL) { - _factory = belle_sip_object_new(LinphoneFactory); + _factory = linphone_factory_new(); atexit(_linphone_factory_destroying_cb); } return _factory; @@ -107,65 +137,72 @@ LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) { return _linphone_vcard_new(); } -char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) { - if (factory->top_resources_dir) return bctbx_strdup(factory->top_resources_dir); - return bctbx_strdup(PACKAGE_DATA_DIR); +const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) { + return factory->top_resources_dir; } void linphone_factory_set_top_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->top_resources_dir) bctbx_free(factory->top_resources_dir); - factory->top_resources_dir = bctbx_strdup(path); + STRING_SET(factory->top_resources_dir, path); } -char * linphone_factory_get_data_resources_dir(const LinphoneFactory *factory) { - if (factory->data_resources_dir) return bctbx_strdup(factory->data_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/linphone", factory->top_resources_dir); - return bctbx_strdup_printf("%s/linphone", PACKAGE_DATA_DIR); +const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory) { + if (factory->data_resources_dir) return factory->data_resources_dir; + if (factory->top_resources_dir){ + STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", factory->top_resources_dir)); + }else{ + STRING_TRANSFER(factory->cached_data_resources_dir, bctbx_strdup_printf("%s/linphone", PACKAGE_DATA_DIR)); + } + return factory->cached_data_resources_dir; } void linphone_factory_set_data_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->data_resources_dir) bctbx_free(factory->data_resources_dir); - factory->data_resources_dir = bctbx_strdup(path); + STRING_SET(factory->data_resources_dir, path); } -char * linphone_factory_get_sound_resources_dir(const LinphoneFactory *factory) { - if (factory->sound_resources_dir) return bctbx_strdup(factory->sound_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/sounds/linphone", factory->top_resources_dir); - return bctbx_strdup(PACKAGE_SOUND_DIR); +const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory) { + if (factory->sound_resources_dir) return factory->sound_resources_dir; + if (factory->top_resources_dir){ + STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/sounds/linphone", factory->top_resources_dir)); + return factory->cached_sound_resources_dir; + } + return PACKAGE_SOUND_DIR; } void linphone_factory_set_sound_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->sound_resources_dir) bctbx_free(factory->sound_resources_dir); - factory->sound_resources_dir = bctbx_strdup(path); + STRING_SET(factory->sound_resources_dir, path); } -char * linphone_factory_get_ring_resources_dir(const LinphoneFactory *factory) { - if (factory->ring_resources_dir) return bctbx_strdup(factory->ring_resources_dir); - if (factory->sound_resources_dir) return bctbx_strdup_printf("%s/rings", factory->sound_resources_dir); - return bctbx_strdup(PACKAGE_RING_DIR); +const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory) { + if (factory->ring_resources_dir) return factory->ring_resources_dir; + if (factory->sound_resources_dir){ + STRING_TRANSFER(factory->cached_sound_resources_dir, bctbx_strdup_printf("%s/rings", factory->sound_resources_dir)); + return factory->cached_sound_resources_dir; + } + return PACKAGE_RING_DIR; } void linphone_factory_set_ring_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->ring_resources_dir) bctbx_free(factory->ring_resources_dir); - factory->ring_resources_dir = bctbx_strdup(path); + STRING_SET(factory->ring_resources_dir, path); } -char * linphone_factory_get_image_resources_dir(const LinphoneFactory *factory) { - if (factory->image_resources_dir) return bctbx_strdup(factory->image_resources_dir); - if (factory->top_resources_dir) return bctbx_strdup_printf("%s/images", factory->top_resources_dir); - return bctbx_strdup_printf("%s/images", PACKAGE_DATA_DIR); +const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory) { + if (factory->image_resources_dir) return factory->image_resources_dir; + if (factory->top_resources_dir) { + STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", factory->top_resources_dir)); + }else{ + STRING_TRANSFER(factory->cached_image_resources_dir, bctbx_strdup_printf("%s/images", PACKAGE_DATA_DIR)); + } + return factory->cached_image_resources_dir; } void linphone_factory_set_image_resources_dir(LinphoneFactory *factory, const char *path) { - if (factory->image_resources_dir) bctbx_free(factory->image_resources_dir); - factory->image_resources_dir = bctbx_strdup(path); + STRING_SET(factory->image_resources_dir, path); } -char * linphone_factory_get_msplugins_dir(const LinphoneFactory *factory) { - return bctbx_strdup(factory->msplugins_dir); +const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory) { + return factory->msplugins_dir; } void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *path) { - if (factory->msplugins_dir) bctbx_free(factory->msplugins_dir); - factory->msplugins_dir = bctbx_strdup(path); + STRING_SET(factory->msplugins_dir, path); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d4c64e416..76bde15aa 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1204,7 +1204,7 @@ static void sound_config_read(LinphoneCore *lc) static void certificates_config_read(LinphoneCore *lc) { LinphoneFactory *factory = linphone_factory_get(); - char *data_dir = linphone_factory_get_data_resources_dir(factory); + const char *data_dir = linphone_factory_get_data_resources_dir(factory); char *root_ca_path = bctbx_strdup_printf("%s/rootca.pem", data_dir); const char *rootca = lp_config_get_string(lc->config,"sip","root_ca", NULL); // If rootca is not existing anymore, we reset it to the default value @@ -1225,7 +1225,6 @@ static void certificates_config_read(LinphoneCore *lc) { linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE)); linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE)); bctbx_free(root_ca_path); - bctbx_free(data_dir); } static void sip_config_read(LinphoneCore *lc) { @@ -2076,8 +2075,8 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig const char *remote_provisioning_uri = NULL; LinphoneFactory *lfactory = linphone_factory_get(); LinphoneCoreCbs *internal_cbs = _linphone_core_cbs_new(); - char *msplugins_dir; - char *image_resources_dir; + const char *msplugins_dir; + const char *image_resources_dir; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -2109,8 +2108,6 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); - if (msplugins_dir) bctbx_free(msplugins_dir); - bctbx_free(image_resources_dir); linphone_core_register_default_codecs(lc); linphone_core_register_offer_answer_providers(lc); /* Get the mediastreamer2 event queue */ diff --git a/coreapi/private.h b/coreapi/private.h index dbbb9ccfd..be8e480ea 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -124,8 +124,11 @@ #ifdef __cplusplus extern "C" { #endif - -#define ms_strdup_safe(str) ((str) ? ms_strdup(str) : NULL) + + +#define STRING_RESET(field) if (field) bctbx_free(field); (field) = NULL +#define STRING_SET(field, value) do{ if (field){bctbx_free(field);field=NULL;}; field=bctbx_strdup(value); }while(0) +#define STRING_TRANSFER(field, newvalue) do{ if (field){bctbx_free(field);field=NULL;}; field=newvalue; }while(0) struct _LinphoneCallParams{ belle_sip_object_t base; diff --git a/gtk/main.c b/gtk/main.c index a7b79400e..8d12ac9ee 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -341,13 +341,12 @@ static int get_ui_file(const char *name, char *path, int pathsize){ snprintf(path,pathsize,"%s/%s.ui",BUILD_TREE_XML_DIR,name); if (bctbx_file_exist(path)!=0){ LinphoneFactory *factory = linphone_factory_get(); - char *data_dir = linphone_factory_get_data_resources_dir(factory); + const char *data_dir = linphone_factory_get_data_resources_dir(factory); snprintf(path,pathsize,"%s/%s.ui",data_dir,name); if (bctbx_file_exist(path)!=0){ g_error("Could not locate neither %s/%s.ui nor %s/%s.ui",BUILD_TREE_XML_DIR,name,data_dir,name); return -1; } - bctbx_free(data_dir); } return 0; } @@ -486,7 +485,7 @@ static void about_url_clicked(GtkAboutDialog *dialog, const char *url, gpointer void linphone_gtk_show_about(void){ struct stat filestat; - char *data_dir; + const char *data_dir; char *license_file; GtkWidget *about; const char *tmp; @@ -501,7 +500,6 @@ void linphone_gtk_show_about(void){ data_dir = linphone_factory_get_data_resources_dir(factory); license_file = bctbx_strdup_printf("%s/COPYING", data_dir); - bctbx_free(data_dir); memset(&filestat,0,sizeof(filestat)); if (stat(license_file,&filestat)!=0){ license_file="COPYING"; @@ -2136,7 +2134,7 @@ static void populate_xdg_data_dirs_envvar(void) { int i; gchar *value; gchar **paths; - char *data_dir; + const char *data_dir; LinphoneFactory *factory = linphone_factory_get(); if(g_getenv("XDG_DATA_DIRS") == NULL) { @@ -2152,7 +2150,6 @@ static void populate_xdg_data_dirs_envvar(void) { g_setenv("XDG_DATA_DIRS", new_value, TRUE); g_free(new_value); } - bctbx_free(data_dir); g_strfreev(paths); #endif } @@ -2168,7 +2165,7 @@ int main(int argc, char *argv[]){ char *chat_messages_db_file, *call_logs_db_file, *friends_db_file; GError *error=NULL; const char *tmp; - char *resources_dir; + const char *resources_dir; char *pixmaps_dir; LinphoneFactory *factory; @@ -2271,7 +2268,6 @@ int main(int argc, char *argv[]){ pixmaps_dir = bctbx_strdup_printf("%s/pixmaps/linphone", resources_dir); add_pixmap_directory(pixmaps_dir); bctbx_free(pixmaps_dir); - bctbx_free(resources_dir); /* Now, look for the factory configuration file, we do it this late since we want to have had time to change directory and to parse diff --git a/gtk/support.c b/gtk/support.c index e2fbfc360..df6006ee0 100644 --- a/gtk/support.c +++ b/gtk/support.c @@ -193,7 +193,7 @@ void linphone_gtk_set_ui_config(const char *key , const char * val){ const char *linphone_gtk_get_sound_path(const char *name){ static char *ret=NULL; const char *file; - char *sound_dir; + const char *sound_dir; LinphoneFactory *factory = linphone_factory_get(); file=linphone_gtk_get_ui_config(name,NULL); @@ -212,7 +212,6 @@ const char *linphone_gtk_get_sound_path(const char *name){ } sound_dir = linphone_factory_get_sound_resources_dir(factory); ret=g_build_filename(sound_dir,name,NULL); - bctbx_free(sound_dir); return ret; } diff --git a/include/linphone/factory.h b/include/linphone/factory.h index c24d9005f..8ff784db1 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -123,7 +123,7 @@ LINPHONE_PUBLIC LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the top directory where the resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory); /** * Set the top directory where the resources are located. @@ -138,7 +138,7 @@ LINPHONE_PUBLIC void linphone_factory_set_top_resources_dir(LinphoneFactory *fac * @param[in] factory LinphoneFactory object * @return The path to the directory where the data resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_data_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_data_resources_dir(LinphoneFactory *factory); /** * Set the directory where the data resources are located. @@ -152,7 +152,7 @@ LINPHONE_PUBLIC void linphone_factory_set_data_resources_dir(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the directory where the sound resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_sound_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_sound_resources_dir(LinphoneFactory *factory); /** * Set the directory where the sound resources are located. @@ -166,7 +166,7 @@ LINPHONE_PUBLIC void linphone_factory_set_sound_resources_dir(LinphoneFactory *f * @param[in] factory LinphoneFactory object * @return The path to the directory where the ring resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_ring_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_ring_resources_dir(LinphoneFactory *factory); /** * Set the directory where the ring resources are located. @@ -180,7 +180,7 @@ LINPHONE_PUBLIC void linphone_factory_set_ring_resources_dir(LinphoneFactory *fa * @param[in] factory LinphoneFactory object * @return The path to the directory where the image resources are located */ -LINPHONE_PUBLIC char * linphone_factory_get_image_resources_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_image_resources_dir(LinphoneFactory *factory); /** * Set the directory where the image resources are located. @@ -194,7 +194,7 @@ LINPHONE_PUBLIC void linphone_factory_set_image_resources_dir(LinphoneFactory *f * @param[in] factory LinphoneFactory object * @return The path to the directory where the mediastreamer2 plugins are located, or NULL if it has not been set */ -LINPHONE_PUBLIC char * linphone_factory_get_msplugins_dir(const LinphoneFactory *factory); +LINPHONE_PUBLIC const char * linphone_factory_get_msplugins_dir(LinphoneFactory *factory); /** * Set the directory where the mediastreamer2 plugins are located. diff --git a/mediastreamer2 b/mediastreamer2 index 1f17b3ba2..b5a000c65 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 1f17b3ba22cb662c1c15655c8248036e7a69baf2 +Subproject commit b5a000c65e109312c1f0b72ce5e9122caec72e4f diff --git a/tools/auto_answer.c b/tools/auto_answer.c index 74a3ae292..d0dc9edcc 100644 --- a/tools/auto_answer.c +++ b/tools/auto_answer.c @@ -141,11 +141,10 @@ int main(int argc, char *argv[]){ linphone_core_enable_echo_cancellation(lc, FALSE); /*no need for local echo cancellation when playing files*/ if (!media_file){ LinphoneFactory *factory = linphone_factory_get(); - char *sound_resources_dir = linphone_factory_get_sound_resources_dir(factory); + const char *sound_resources_dir = linphone_factory_get_sound_resources_dir(factory); char *play_file = bctbx_strdup_printf("%s/hello16000.wav", sound_resources_dir); linphone_core_set_play_file(lc, play_file); bctbx_free(play_file); - bctbx_free(sound_resources_dir); linphone_core_set_preferred_framerate(lc,5); }else{ PayloadType *pt = linphone_core_find_payload_type(lc, "opus", 48000, -1); From b0f87c2a3db749269c87b348c8522c3f335d968f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 23 Mar 2017 14:43:58 +0100 Subject: [PATCH 02/11] chore(submodules): update mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index b5a000c65..c1dc217a0 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit b5a000c65e109312c1f0b72ce5e9122caec72e4f +Subproject commit c1dc217a061f0af832151e98e9ad8db6686c45ca From 5b861f2b80f4febda50f82a716d6b811ae5f5072 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 23 Mar 2017 16:49:46 +0100 Subject: [PATCH 03/11] chore(submodules): update mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index c1dc217a0..dbd591809 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit c1dc217a061f0af832151e98e9ad8db6686c45ca +Subproject commit dbd5918096518feaf9a3be55ca7a834fa4dafe18 From a0aae6c83af3913c1885ab485f75b755fb75584d Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 23 Mar 2017 10:44:15 +0100 Subject: [PATCH 04/11] fix group mode for cxx wrapper --- cmake/LinphoneConfig.cmake.in | 7 +++++++ coreapi/help/CMakeLists.txt | 8 ++++++-- wrappers/cpp/LinphoneCxxConfig.cmake.in | 7 +++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cmake/LinphoneConfig.cmake.in b/cmake/LinphoneConfig.cmake.in index afb47f1db..25ab6cc6e 100644 --- a/cmake/LinphoneConfig.cmake.in +++ b/cmake/LinphoneConfig.cmake.in @@ -32,6 +32,13 @@ if(NOT LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) include("${CMAKE_CURRENT_LIST_DIR}/LinphoneTargets.cmake") endif() +if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_ms2_CONFIG_DIR}/Mediastreamer2Config.cmake") + include("${EP_bellesip_CONFIG_DIR}/BelleSIPConfig.cmake") +else() + find_package(Mediastreamer2 REQUIRED) + find_package(BelleSIP REQUIRED) +endif() if(@ENABLE_SHARED@) set(LINPHONE_TARGETNAME linphone) diff --git a/coreapi/help/CMakeLists.txt b/coreapi/help/CMakeLists.txt index 0b9e3b3fa..21051817a 100644 --- a/coreapi/help/CMakeLists.txt +++ b/coreapi/help/CMakeLists.txt @@ -20,7 +20,7 @@ # ############################################################################ -if (ENABLE_DOC) +if (ENABLE_DOC OR CXX_WRAPPER) find_package(Doxygen) if(DOXYGEN_FOUND) if(DOXYGEN_DOT_FOUND) @@ -39,7 +39,11 @@ if (ENABLE_DOC) install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doc/html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml" DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/linphone-${LINPHONE_VERSION}") else() - message(WARNING "The dot program is needed to generate the linphone documentation. You can get it from http://www.graphviz.org/.") + if (CXX_WRAPPER) + message(FATAL_ERROR "The dot program is needed to generate the linphone documentation. You can get it from http://www.graphviz.org/.") + else() + message(WARNING "The dot program is needed to generate the linphone documentation. You can get it from http://www.graphviz.org/.") + endif() endif() endif() endif() diff --git a/wrappers/cpp/LinphoneCxxConfig.cmake.in b/wrappers/cpp/LinphoneCxxConfig.cmake.in index 6ed42d720..c3a0f08d2 100644 --- a/wrappers/cpp/LinphoneCxxConfig.cmake.in +++ b/wrappers/cpp/LinphoneCxxConfig.cmake.in @@ -29,6 +29,13 @@ # LINPHONECXX_INCLUDE_DIRS - the linphone++ include directory # LINPHONECXX_LIBRARIES - The libraries needed to use linphone++ # LINPHONECXX_LDFLAGS - The linking flags needed to use linphone++ +if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_ms2_CONFIG_DIR}/Mediastreamer2Config.cmake") + include("${EP_bellesip_CONFIG_DIR}/BelleSIPConfig.cmake") +else() + find_package(BelleSIP) + find_package(Linphone) +endif() include("${CMAKE_CURRENT_LIST_DIR}/LinphoneCxxTargets.cmake") set(LINPHONECXX_LDFLAGS "") From 5e382aa5033c96a68ba336b06eae6cbb8ed8e5e5 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 23 Mar 2017 18:22:03 +0100 Subject: [PATCH 05/11] fix LinphoneCxxConfig for group mode --- mediastreamer2 | 2 +- wrappers/cpp/LinphoneCxxConfig.cmake.in | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index dbd591809..22417d986 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit dbd5918096518feaf9a3be55ca7a834fa4dafe18 +Subproject commit 22417d98696e4368c314efe862caaf8c62845b85 diff --git a/wrappers/cpp/LinphoneCxxConfig.cmake.in b/wrappers/cpp/LinphoneCxxConfig.cmake.in index c3a0f08d2..6bc4fb433 100644 --- a/wrappers/cpp/LinphoneCxxConfig.cmake.in +++ b/wrappers/cpp/LinphoneCxxConfig.cmake.in @@ -29,23 +29,21 @@ # LINPHONECXX_INCLUDE_DIRS - the linphone++ include directory # LINPHONECXX_LIBRARIES - The libraries needed to use linphone++ # LINPHONECXX_LDFLAGS - The linking flags needed to use linphone++ -if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) - include("${EP_ms2_CONFIG_DIR}/Mediastreamer2Config.cmake") - include("${EP_bellesip_CONFIG_DIR}/BelleSIPConfig.cmake") -else() - find_package(BelleSIP) - find_package(Linphone) +if (NOT LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${CMAKE_CURRENT_LIST_DIR}/LinphoneCxxTargets.cmake") endif() - -include("${CMAKE_CURRENT_LIST_DIR}/LinphoneCxxTargets.cmake") set(LINPHONECXX_LDFLAGS "") set(LINPHONECXX_CPPFLAGS "") set(LINPHONECXX_LIBRARIES linphone++) #get_target_property(LINPHONECXX_INCLUDE_DIRS linphone++ INTERFACE_INCLUDE_DIRECTORIES) #list(INSERT LINPHONECXX_INCLUDE_DIRS 0 "@CMAKE_INSTALL_FULL_INCLUDEDIR@") -set(LINPHONECXX_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + list(APPEND LINPHONECXX_INCLUDE_DIRS "@CMAKE_CURRENT_BINARY_DIR@/include") + list(APPEND LINPHONECXX_INCLUDE_DIRS "${EP_linphone_INCLUDE_DIR}/../wrappers/cpp") +else() + set(LINPHONECXX_INCLUDE_DIRS "@CMAKE_INSTALL_FULL_INCLUDEDIR@") +endif() list(REMOVE_DUPLICATES LINPHONECXX_INCLUDE_DIRS) set(LINPHONECXX_FOUND 1) - From 6409bed254e2d6ef72a1e9069a36a1de38e9aa77 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Fri, 24 Mar 2017 08:46:25 +0100 Subject: [PATCH 06/11] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 22417d986..d2f6fa80d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 22417d98696e4368c314efe862caaf8c62845b85 +Subproject commit d2f6fa80d62853657a177d60b8b2f3acb6ca644b From 3ec8d3669de77117f7ab9b9dbfd42a121bcc2dff Mon Sep 17 00:00:00 2001 From: Benjamin Reis Date: Fri, 24 Mar 2017 15:57:58 +0100 Subject: [PATCH 07/11] Fix build issue --- mediastreamer2 | 2 +- tester/liblinphone_tester_ios.m | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index d2f6fa80d..0dbcd131d 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d2f6fa80d62853657a177d60b8b2f3acb6ca644b +Subproject commit 0dbcd131d61a15df544ba74ae8df60fc0eccb4a1 diff --git a/tester/liblinphone_tester_ios.m b/tester/liblinphone_tester_ios.m index 424da58d5..6f3e54495 100644 --- a/tester/liblinphone_tester_ios.m +++ b/tester/liblinphone_tester_ios.m @@ -17,6 +17,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "TargetConditionals.h" #if TARGET_OS_IPHONE #import From 26c0dccfebdba96c25ab8166f60f8d38f5643c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Fri, 24 Mar 2017 14:01:28 +0100 Subject: [PATCH 08/11] C++ wrapper: pubilc structures support --- wrappers/cpp/CMakeLists.txt | 1 + wrappers/cpp/abstractapi.py | 66 ++++++++++++------ wrappers/cpp/class_header.mustache | 18 ++++- wrappers/cpp/class_impl.mustache | 21 ++++++ wrappers/cpp/genwrapper.py | 105 ++++++++++++++++++----------- wrappers/cpp/object.cc | 2 +- wrappers/cpp/object.hh | 16 ++++- wrappers/cpp/tools.hh | 48 +++++++++++-- 8 files changed, 207 insertions(+), 70 deletions(-) diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index 2059de15c..4720a3054 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -38,6 +38,7 @@ target_link_libraries(linphone++ target_include_directories(linphone++ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include PRIVATE ${CMAKE_BINARY_DIR}/include + PRIVATE ${CMAKE_SOURCE_DIR}/include PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PRIVATE ${BCTOOLBOX_INCLUDE_DIRS} PRIVATE ${BELLESIP_INCLUDE_DIRS} diff --git a/wrappers/cpp/abstractapi.py b/wrappers/cpp/abstractapi.py index bc6da71bd..ef27d4ec0 100644 --- a/wrappers/cpp/abstractapi.py +++ b/wrappers/cpp/abstractapi.py @@ -178,7 +178,7 @@ class ArgName(Name): return Name.to_snake_case(self) -class PropertyName(Name): +class PropertyName(ArgName): pass @@ -357,6 +357,7 @@ class Property(DocumentableObject): DocumentableObject.__init__(self, name) self._setter = None self._getter = None + self._type = None def set_setter(self, setter): self._setter = setter @@ -367,6 +368,8 @@ class Property(DocumentableObject): def set_getter(self, getter): self._getter = getter + if self._type is None: + self._type = getter.returnType getter.parent = self def get_getter(self): @@ -384,6 +387,7 @@ class Class(DocumentableObject): self.classMethods = [] self._listenerInterface = None self.multilistener = False + self.refcountable = False def add_property(self, property): self.properties.append(property) @@ -482,13 +486,21 @@ class CParser(object): 'linphone_friend_new', # was deprecated when the wrapper generator was made 'linphone_friend_new_with_address', # was deprecated when the wrapper generator was made 'linphone_core_get_sound_source', # was deprecated when the wrapper generator was made - 'linphone_core_set_sound_source'] # was deprecated when the wrapper generator was made + 'linphone_core_set_sound_source', # was deprecated when the wrapper generator was made + 'linphone_core_get_sip_transports', # not wrappable + 'linphone_core_get_sip_transports_used'] # not wrappable self.classBl = ['LinphoneImEncryptionEngine', 'LinphoneImEncryptionEngineCbs', 'LinphoneImNotifPolicy', 'LpConfig', - 'LinphoneCallStats'] # temporarly blacklisted + 'LinphoneErrorInfo', + 'LinphonePayloadType', + 'LinphonePlayer'] # temporarly blacklisted + + # list of classes that must be concidered as refcountable even if + # they are no ref()/unref() methods + self.forcedRefcountableClasses = ['LinphoneFactory'] self.cProject = cProject @@ -531,8 +543,19 @@ class CParser(object): pass except Error as e: print('Could not parse \'{0}\' class: {1}'.format(_class.name, e.args[0])) + CParser._fix_all_types(self) + + def _class_is_refcountable(self, _class): + if _class.name in self.forcedRefcountableClasses: + return True + + for method in _class.instanceMethods: + if method.startswith(_class.cFunctionPrefix) and method[len(_class.cFunctionPrefix):] == 'ref': + return True + return False + def _fix_all_types(self): for _class in self.classesIndex.values() + self.interfacesIndex.values(): if _class is not None: @@ -563,24 +586,24 @@ class CParser(object): except Error as e: print('warning: some types could not be fixed in {0}() function: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) - def _fix_type(self, type): - if isinstance(type, EnumType) and type.desc is None: - type.desc = self.enumsIndex[type.name] - elif isinstance(type, ClassType) and type.desc is None: - if type.name in self.classesIndex: - type.desc = self.classesIndex[type.name] + def _fix_type(self, _type): + if isinstance(_type, EnumType) and _type.desc is None: + _type.desc = self.enumsIndex[_type.name] + elif isinstance(_type, ClassType) and _type.desc is None: + if _type.name in self.classesIndex: + _type.desc = self.classesIndex[_type.name] else: - type.desc = self.interfacesIndex[type.name] - elif isinstance(type, ListType) and type.containedTypeDesc is None: - if type.containedTypeName in self.classesIndex: - type.containedTypeDesc = ClassType(type.containedTypeName, classDesc=self.classesIndex[type.containedTypeName]) - elif type.containedTypeName in self.interfacesIndex: - type.containedTypeDesc = ClassType(type.containedTypeName, classDesc=self.interfacesIndex[type.containedTypeName]) - elif type.containedTypeName in self.enumsIndex: - type.containedTypeDesc = EnumType(type.containedTypeName, enumDesc=self.enumsIndex[type.containedTypeName]) + _type.desc = self.interfacesIndex[_type.name] + elif isinstance(_type, ListType) and _type.containedTypeDesc is None: + if _type.containedTypeName in self.classesIndex: + _type.containedTypeDesc = ClassType(_type.containedTypeName, classDesc=self.classesIndex[_type.containedTypeName]) + elif _type.containedTypeName in self.interfacesIndex: + _type.containedTypeDesc = ClassType(_type.containedTypeName, classDesc=self.interfacesIndex[_type.containedTypeName]) + elif _type.containedTypeName in self.enumsIndex: + _type.containedTypeDesc = EnumType(_type.containedTypeName, enumDesc=self.enumsIndex[_type.containedTypeName]) else: - if type.containedTypeName is not None: - type.containedTypeDesc = CParser.parse_c_base_type(self, type.containedTypeName) + if _type.containedTypeName is not None: + _type.containedTypeDesc = CParser.parse_c_base_type(self, _type.containedTypeName) else: raise Error('bctbx_list_t type without specified contained type') @@ -621,6 +644,7 @@ class CParser(object): name = ClassName() name.from_camel_case(cclass.name, namespace=self.namespace.name) _class = Class(name) + _class.refcountable = CParser._class_is_refcountable(self, cclass) for cproperty in cclass.properties.values(): try: @@ -755,10 +779,8 @@ class CParser(object): elif cType.ctype in self.enumsIndex: absType = EnumType(cType.ctype, enumDesc=self.enumsIndex[cType.ctype]) elif cType.ctype in self.classesIndex or cType.ctype in self.interfacesIndex: - #params = {'classDesc': self.classesIndex[cType.ctype]} - #if 'const' in cType.completeType.split(' '): - #params['isconst'] = True absType = ClassType(cType.ctype) + absType.isconst = cType.completeType.startswith('const ') elif cType.ctype == self.cListType: absType = ListType(cType.containedType) else: diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache index 160bb9b67..d3ed12f23 100644 --- a/wrappers/cpp/class_header.mustache +++ b/wrappers/cpp/class_header.mustache @@ -43,14 +43,23 @@ namespace linphone { {{/priorDeclarations}} {{#_class}} - class {{className}}: public {{{parentClassName}}} { + class {{className}}{{#parentClassName}}: public {{{parentClassName}}}{{/parentClassName}} { {{#friendClasses}} friend class {{name}}; {{/friendClasses}} public: {{#isNotListener}} + {{#isrefcountable}} {{{className}}}(void *ptr, bool takeRef=true); + {{/isrefcountable}} + {{#isnotrefcountable}} + LINPHONECXX_PUBLIC {{{className}}}(); + LINPHONECXX_PUBLIC {{{className}}}(const {{{className}}} &src); + {{{className}}}(const void *src); + LINPHONECXX_PUBLIC ~{{{className}}}(); + LINPHONECXX_PUBLIC const void *c_struct() const {return mPrivPtr;} + {{/isnotrefcountable}} {{/isNotListener}} {{#ismonolistenable}} @@ -71,6 +80,7 @@ namespace linphone { {{#isVcard}} LINPHONECXX_PUBLIC std::shared_ptr &getVcard(); {{/isVcard}} + {{#methods}} {{{prototype}}} @@ -91,7 +101,11 @@ namespace linphone { private: void *mCallbacks; {{/ismultilistenable}} - + + {{#isnotrefcountable}} + private: + void *mPrivPtr; + {{/isnotrefcountable}} }; {{/_class}} diff --git a/wrappers/cpp/class_impl.mustache b/wrappers/cpp/class_impl.mustache index a9e3aec11..142413ff9 100644 --- a/wrappers/cpp/class_impl.mustache +++ b/wrappers/cpp/class_impl.mustache @@ -47,12 +47,33 @@ static {{{returnType}}} {{{cbName}}}({{{declArgs}}}) { {{/wrapperCbs}} {{#isNotListener}} +{{#isrefcountable}} {{{namespace}}}::{{{className}}}::{{{className}}}(void *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) { {{#ismultilistenable}} mCallbacks = ({{{cListenerName}}} *)createCallbacks(&getListeners()); {{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks); {{/ismultilistenable}} } +{{/isrefcountable}} + +{{#isnotrefcountable}} +{{{namespace}}}::{{{className}}}::{{{className}}}() { + mPrivPtr = new {{{cClassName}}}; + memset(mPrivPtr, 0, sizeof({{{cClassName}}})); +} + +{{{namespace}}}::{{{className}}}::{{{className}}}(const {{{className}}} &src) { + mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src.mPrivPtr); +} + +{{{namespace}}}::{{{className}}}::{{{className}}}(const void *src) { + mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src); +} + +{{{namespace}}}::{{{className}}}::~{{{className}}}() { + delete ({{{cClassName}}} *)mPrivPtr; +} +{{/isnotrefcountable}} {{/isNotListener}} {{#ismonolistenable}} diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index 14c94fa1c..751c90428 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -66,22 +66,24 @@ class CppTranslator(object): ismonolistenable = (islistenable and not _class.multilistener) ismultilistenable = (islistenable and _class.multilistener) - classDict = {} - classDict['islistenable'] = islistenable - classDict['isnotlistenable'] = not islistenable - classDict['ismonolistenable'] = ismonolistenable - classDict['ismultilistenable'] = ismultilistenable - classDict['isNotListener'] = True - classDict['isfactory'] = (_class.name.to_c() == 'LinphoneFactory') - classDict['isVcard'] = (_class.name.to_c() == 'LinphoneVcard') - classDict['parentClassName'] = None - classDict['className'] = CppTranslator.translate_class_name(_class.name) - classDict['cClassName'] = '::' + _class.name.to_c() - classDict['parentClassName'] = 'Object' - classDict['methods'] = [] - classDict['staticMethods'] = [] - classDict['wrapperCbs'] = [] - classDict['friendClasses'] = [] + classDict = { + 'islistenable' : islistenable, + 'isnotlistenable' : not islistenable, + 'ismonolistenable' : ismonolistenable, + 'ismultilistenable' : ismultilistenable, + 'isrefcountable' : _class.refcountable, + 'isnotrefcountable' : not _class.refcountable, + 'isNotListener' : True, + 'isfactory' : (_class.name.to_c() == 'LinphoneFactory'), + 'isVcard' : (_class.name.to_c() == 'LinphoneVcard'), + 'className' : CppTranslator.translate_class_name(_class.name), + 'cClassName' : '::' + _class.name.to_c(), + 'parentClassName' : 'Object' if _class.refcountable else None, + 'methods' : [], + 'staticMethods' : [], + 'wrapperCbs' : [], + 'friendClasses' : [] + } if _class.name.to_c() == 'LinphoneCore': classDict['friendClasses'].append({'name': 'Factory'}); @@ -279,20 +281,33 @@ class CppTranslator(object): elif type(exprtype) is AbsApi.EnumType: cExpr = '(::{0}){1}'.format(exprtype.desc.name.to_c(), cppExpr) elif type(exprtype) is AbsApi.ClassType: - param = {} - param['ptrType'] = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace) - param['ptrType'] = CppTranslator.sharedPtrTypeExtractor.match(param['ptrType']).group(2) - param['cPtrType'] = exprtype.desc.name.to_c() - param['cppExpr'] = cppExpr - param['object'] = 'const Object' if exprtype.isconst else 'Object' - cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param) + cPtrType = exprtype.desc.name.to_c() + if exprtype.desc.refcountable: + ptrType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace) + ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2) + param = { + 'ptrType' : ptrType, + 'cPtrType': cPtrType, + 'cppExpr' : cppExpr, + 'object' : 'const Object' if exprtype.isconst else 'Object' + } + cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param) + else: + cExpr = '(const ::{_type} *)({expr}).c_struct()'.format(_type=cPtrType, expr=cppExpr) elif type(exprtype) is AbsApi.ListType: if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: ptrType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace) - ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2) - cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format(ptrType, cppExpr) + if exprtype.containedTypeDesc.desc.refcountable: + ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2) + cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format(ptrType, cppExpr) + else: + cType = exprtype.containedTypeDesc.desc.name.to_c() + if exprtype.isconst: + cExpr = 'StructBctbxListWrapper<{0},{1}>({2}).c_list()'.format(ptrType, cType, cppExpr) + else: + cExpr = 'StructBctbxListWrapper<{0},{1}>::cppListToBctbxList({2})'.format(ptrType, cType, cppExpr) else: raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported') @@ -315,19 +330,26 @@ class CppTranslator(object): return '({0}){1}'.format(cppEnumName, cExpr) elif type(exprtype) is AbsApi.ClassType: cppReturnType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace) - cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) - - if type(exprtype.parent) is AbsApi.Method and len(exprtype.parent.name.words) >=1 and (exprtype.parent.name.words == ['new'] or exprtype.parent.name.words[0] == 'create'): - return 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1}, false)'.format(cppReturnType, cExpr) + if exprtype.desc.refcountable: + cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) + + if type(exprtype.parent) is AbsApi.Method and len(exprtype.parent.name.words) >=1 and (exprtype.parent.name.words == ['new'] or exprtype.parent.name.words[0] == 'create'): + return 'Object::cPtrToSharedPtr<{0}>({1}, false)'.format(cppReturnType, cExpr) + else: + return 'Object::cPtrToSharedPtr<{0}>({1})'.format(cppReturnType, cExpr) else: - return 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1})'.format(cppReturnType, cExpr) + return '{0}({1})'.format(exprtype.desc.name.to_camel_case(), cExpr); elif type(exprtype) is AbsApi.ListType: if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: cppReturnType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace) - cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) - return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr) + if exprtype.containedTypeDesc.desc.refcountable: + cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) + return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr) + else: + cType = exprtype.containedTypeDesc.desc.name.to_c() + return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2})'.format(cppReturnType, cType, cExpr) else: raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported') else: @@ -429,13 +451,18 @@ class CppTranslator(object): res = CppTranslator.translate_class_name(_type.desc.name, recursive=True, topAncestor=nsName) - if _type.isconst: - res = 'const ' + res - - if type(_type.parent) is AbsApi.Argument: - return 'const std::shared_ptr<{0}> &'.format(res) + if _type.desc.refcountable: + if _type.isconst: + res = 'const ' + res + if type(_type.parent) is AbsApi.Argument: + return 'const std::shared_ptr<{0}> &'.format(res) + else: + return 'std::shared_ptr<{0}>'.format(res) else: - return 'std::shared_ptr<{0}>'.format(res) + if type(_type.parent) is AbsApi.Argument: + return 'const {0} &'.format(res) + else: + return '{0}'.format(res) def translate_list_type(self, _type, **params): if _type.containedTypeDesc is None: @@ -679,6 +706,8 @@ def main(): render(renderer, header, includedir + '/enums.hh') mainHeader = MainHeader() + mainHeader.add_include('enums.hh') + impl = ClassImpl() for _class in parser.classesIndex.values() + parser.interfacesIndex.values(): diff --git a/wrappers/cpp/object.cc b/wrappers/cpp/object.cc index eb99658d8..cf23c6360 100644 --- a/wrappers/cpp/object.cc +++ b/wrappers/cpp/object.cc @@ -72,7 +72,7 @@ std::map &Object::getUserData() const { return *userData; } -Object *Object::getBackPtrFromCPtr(void *ptr) { +linphone::Object *linphone::Object::getBackPtrFromCPtr(const void *ptr) { return (Object *)belle_sip_object_data_get((::belle_sip_object_t *)ptr, "cpp_object"); } diff --git a/wrappers/cpp/object.hh b/wrappers/cpp/object.hh index 61a94676a..d069856d3 100644 --- a/wrappers/cpp/object.hh +++ b/wrappers/cpp/object.hh @@ -85,11 +85,25 @@ namespace linphone { } } } + template + static std::shared_ptr cPtrToSharedPtr(const void *ptr, bool takeRef=true) { + if (ptr == NULL) { + return nullptr; + } else { + Object *cppPtr = getBackPtrFromCPtr(ptr); + if (cppPtr == NULL) { + return std::make_shared((void *)ptr, takeRef); + } else { + return std::static_pointer_cast(cppPtr->shared_from_this()); + } + } + } static void *sharedPtrToCPtr(const std::shared_ptr &sharedPtr); + private: LINPHONECXX_PUBLIC std::map &getUserData() const; - static Object *getBackPtrFromCPtr(void *ptr); + static Object *getBackPtrFromCPtr(const void *ptr); template static void deleteSharedPtr(std::shared_ptr *ptr) {if (ptr != NULL) delete ptr;} static void deleteString(std::string *str) {if (str != NULL) delete str;} diff --git a/wrappers/cpp/tools.hh b/wrappers/cpp/tools.hh index 81c5dbcdb..5d2fae0da 100644 --- a/wrappers/cpp/tools.hh +++ b/wrappers/cpp/tools.hh @@ -43,14 +43,12 @@ namespace linphone { class ObjectBctbxListWrapper: public AbstractBctbxListWrapper { public: ObjectBctbxListWrapper(const std::list > &cppList) { - for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { - ::belle_sip_object_t *cPtr = (::belle_sip_object_t *)Object::sharedPtrToCPtr(std::static_pointer_cast(*it)); - if (cPtr != NULL) belle_sip_object_ref(cPtr); - mCList = bctbx_list_append(mCList, cPtr); - } + mCList = cppListToBctbxList(cppList); } virtual ~ObjectBctbxListWrapper() { - mCList = bctbx_list_free_with_data(mCList, unrefData); + if (mCList != NULL) { + bctbx_list_free_with_data(mCList, unrefData); + } } static std::list > bctbxListToCppList(const ::bctbx_list_t *bctbxList) { std::list > cppList; @@ -60,6 +58,15 @@ namespace linphone { } return cppList; } + static ::bctbx_list_t *cppListToBctbxList(const std::list > &cppList) { + bctbx_list_t *cList = NULL; + for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { + ::belle_sip_object_t *cPtr = (::belle_sip_object_t *)Object::sharedPtrToCPtr(std::static_pointer_cast(*it)); + if (cPtr != NULL) belle_sip_object_ref(cPtr); + cList = bctbx_list_append(cList, cPtr); + } + return cList; + } private: static void unrefData(void *data) { @@ -75,6 +82,35 @@ namespace linphone { static std::list bctbxListToCppList(const ::bctbx_list_t *bctbxList); }; + + template + class StructBctbxListWrapper: public AbstractBctbxListWrapper { + public: + StructBctbxListWrapper(const std::list &cppList): AbstractBctbxListWrapper() { + mCList = cppListToBctbxList(cppList); + } + virtual ~StructBctbxListWrapper() { + bctbx_list_free_with_data(mCList, (bctbx_list_free_func)deleteCStruct); + } + static std::list bctbxListToCppList(const ::bctbx_list_t *bctbxList) { + std::list cppList; + for(const bctbx_list_t *it = bctbx_list_first_elem(bctbxList); it != NULL; it = bctbx_list_next(it)) { + cppList->push_back(T(it->data)); + } + return cppList; + } + static bctbx_list_t *cppListToBctbxList(const std::list &cppList) { + bctbx_list_t *cList = NULL; + for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { + cList = bctbx_list_append(cList, new U(it->c_struct())); + } + return cList; + } + + private: + static void deleteCStruct(U *cStruct) {delete cStruct;} + }; + class StringUtilities { public: static std::string cStringToCpp(const char *cstr); From a04ec858f59314c359d5b55b69d33324990c6803 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 27 Mar 2017 13:51:14 +0200 Subject: [PATCH 09/11] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 0dbcd131d..f6eb05f48 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 0dbcd131d61a15df544ba74ae8df60fc0eccb4a1 +Subproject commit f6eb05f482cc374cff83302a5f0cde43ca0b8418 From 1c104010f65c736fe499bbfdb7c67c8e8c484568 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 27 Mar 2017 13:51:46 +0200 Subject: [PATCH 10/11] Add API and config parameter to define the echo canceller filter name to use. --- coreapi/linphonecore.c | 1 + coreapi/lpconfig.c | 8 +++++--- coreapi/misc.c | 11 +++++++++++ include/linphone/core.h | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 76bde15aa..7d85d2717 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1186,6 +1186,7 @@ static void sound_config_read(LinphoneCore *lc) #endif tmp=lp_config_get_int(lc->config,"sound","echocancellation",tmp); linphone_core_enable_echo_cancellation(lc,tmp); + linphone_core_set_echo_canceller_filter_name(lc, linphone_core_get_echo_canceller_filter_name(lc)); linphone_core_enable_echo_limiter(lc, lp_config_get_int(lc->config,"sound","echolimiter",0)); linphone_core_enable_agc(lc, diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index c16b827ac..296b0fb73 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -481,9 +481,11 @@ int linphone_config_read_file(LpConfig *lpconfig, const char *filename){ } void lp_item_set_value(LpItem *item, const char *value){ - char *prev_value=item->value; - item->value=ortp_strdup(value); - ortp_free(prev_value); + if (item->value != value) { + char *prev_value=item->value; + item->value=ortp_strdup(value); + ortp_free(prev_value); + } } diff --git a/coreapi/misc.c b/coreapi/misc.c index 3d58237c9..c57dfe764 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1270,6 +1270,17 @@ const char *linphone_core_get_video_display_filter(LinphoneCore *lc){ return lp_config_get_string(lc->config,"video","displaytype",NULL); } +void linphone_core_set_echo_canceller_filter_name(LinphoneCore *lc, const char *filtername) { + lp_config_set_string(lc->config, "sound", "ec_filter", filtername); + if (filtername != NULL) { + ms_factory_set_echo_canceller_filter_name(lc->factory, filtername); + } +} + +const char * linphone_core_get_echo_canceller_filter_name(const LinphoneCore *lc) { + return lp_config_get_string(lc->config, "sound", "ec_filter", NULL); +} + /** * Queue a task into the main loop. The data pointer must remain valid until the task is completed. * task_fun must return BELLE_SIP_STOP when job is finished. diff --git a/include/linphone/core.h b/include/linphone/core.h index 568a17672..c27a6ce2b 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -4145,6 +4145,23 @@ LINPHONE_PUBLIC const char *linphone_core_get_video_display_filter(LinphoneCore **/ LINPHONE_PUBLIC void linphone_core_set_video_display_filter(LinphoneCore *lc, const char *filtername); +/** + * Get the name of the mediastreamer2 filter used for echo cancelling. + * @param[in] lc LinphoneCore object + * @return The name of the mediastreamer2 filter used for echo cancelling + * @ingroup media_parameters + */ +LINPHONE_PUBLIC const char * linphone_core_get_echo_canceller_filter_name(const LinphoneCore *lc); + +/** + * Set the name of the mediastreamer2 filter to be used for echo cancelling. + * This is for advanced users of the library. + * @param[in] lc LinphoneCore object + * @param[in] filtername The name of the mediastreamer2 filter to be used for echo cancelling + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_set_echo_canceller_filter_name(LinphoneCore *lc, const char *filtername); + /** Contact Providers */ From cb194fdce31155ebb60e46b4843966aa3a9d0c8c Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 27 Mar 2017 15:22:42 +0200 Subject: [PATCH 11/11] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index f6eb05f48..b937df188 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit f6eb05f482cc374cff83302a5f0cde43ca0b8418 +Subproject commit b937df188829f73c3f5db35ff0191aa695f27884