diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bab56e2c..0411ca84c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,6 @@ option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES) option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES) option(ENABLE_UPNP "Build with uPnP support." YES) option(ENABLE_VIDEO "Build with video support." YES) -cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO) option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO) @@ -82,16 +81,6 @@ if(MSVC) ) endif() endif() - if(ENABLE_ASSISTANT) - if(NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip") - message(STATUS "Installing libsoup") - file(DOWNLOAD http://www.linphone.org/files/libsoup_2.24.0-1_win32.zip "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip" SHOW_PROGRESS) - execute_process( - COMMAND "${CMAKE_COMMAND}" "-E" "tar" "x" "${CMAKE_CURRENT_BINARY_DIR}/libsoup.zip" - WORKING_DIRECTORY "${CMAKE_INSTALL_PREFIX}" - ) - endif() - endif() endif() find_package(BelleSIP REQUIRED) @@ -131,15 +120,6 @@ if(ENABLE_NOTIFY) set(ENABLE_NOTIFY OFF CACHE BOOL "Enable libnotify support." FORCE) endif() endif() -if(ENABLE_ASSISTANT) - find_package(Soup) - if(SOUP_FOUND) - set(BUILD_WIZARD 1) - else() - message(WARNING "Could not find the soup library!") - set(ENABLE_ASSISTANT OFF CACHE BOOL "Turn on assistant compiling." FORCE) - endif() -endif() find_package(Gettext) @@ -163,9 +143,6 @@ endif() if(ENABLE_TUNNEL) include_directories(${TUNNEL_INCLUDE_DIRS}) endif() -if(ENABLE_ASSISTANT) - include_directories(${SOUP_INCLUDE_DIRS}) -endif() if(ENABLE_DEBUG_LOGS) add_definitions("-DDEBUG") endif() diff --git a/README b/README index 94ad9602a..7e0b97524 100644 --- a/README +++ b/README @@ -26,7 +26,6 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol. - theora (optional) + gsm codec (gsm source package or libgsm-dev or gsm-devel) (optional) + libreadline (optional: for convenient command line in linphonec) - + libsoup (optional: for wizard - account creation assistant) + libsqlite3 (optional : for a local history of chat messages) + if you want uPnP support (optional): - libupnp (version 1.6 branch (not patched with 18-url-upnpstrings.patch)) @@ -39,7 +38,7 @@ libglew1.6-dev libv4l-dev libxml2-dev + for optional library $ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev \ -libsoup2.4-dev libsqlite3-dev libupnp4-dev libsrtp-dev +libsqlite3-dev libupnp4-dev libsrtp-dev + Install zrtp (optional), for unbreakable call encryption $ git clone git://git.linphone.org:bzrtp diff --git a/README.macos.md b/README.macos.md index a3c003909..004e9f9a0 100644 --- a/README.macos.md +++ b/README.macos.md @@ -31,7 +31,7 @@ In order to enable generation of bundle for older MacOS version, it is recommend Install `GTK`. It is recommended to use the `quartz` backend for better integration. - sudo port install gtk2 +quartz +no_x11 libsoup + sudo port install gtk2 +quartz +no_x11 sudo port install gtk-osx-application +no_python sudo port install hicolor-icon-theme @@ -51,7 +51,7 @@ Install `GTK`. It is recommended to use the `quartz` backend for better integrat brew install cairo --without-x11 brew install gtk+ --without-x11 - brew install gtk-mac-integration libsoup hicolor-icon-theme + brew install gtk-mac-integration hicolor-icon-theme ### Building Linphone diff --git a/build/android/config.h b/build/android/config.h index d57ed6264..9b6d33412 100644 --- a/build/android/config.h +++ b/build/android/config.h @@ -7,9 +7,6 @@ /* Define if tools enabled */ /* #undef BUILD_TOOLS */ -/* Define if wizard enabled */ -/* #undef BUILD_WIZARD */ - /* Tells whether localisation is possible */ /* #undef ENABLE_NLS */ diff --git a/cmake/FindSoup.cmake b/cmake/FindSoup.cmake deleted file mode 100644 index 3aeffaefa..000000000 --- a/cmake/FindSoup.cmake +++ /dev/null @@ -1,65 +0,0 @@ -############################################################################ -# FindSoup.cmake -# Copyright (C) 2014 Belledonne Communications, Grenoble France -# -############################################################################ -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# 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. -# -############################################################################ -# -# - Find the soup include file and library -# -# SOUP_FOUND - system has libsoup -# SOUP_INCLUDE_DIRS - the libsoup include directory -# SOUP_LIBRARIES - The libraries needed to use libsoup - -if(WIN32) - set(GTK2_ADDITIONAL_SUFFIXES "../lib/glib-2.0/include" "../lib/gtk-2.0/include") -endif() -find_package(GTK2 2.18 REQUIRED gtk) - -set(_SOUP_ROOT_PATHS - ${CMAKE_INSTALL_PREFIX} -) - -find_path(SOUP_INCLUDE_DIRS - NAMES libsoup/soup.h - HINTS _SOUP_ROOT_PATHS - PATH_SUFFIXES include/libsoup-2.4 -) - -if(SOUP_INCLUDE_DIRS) - set(HAVE_LIBSOUP_SOUP_H 1) - list(APPEND SOUP_INCLUDE_DIRS ${GTK2_INCLUDE_DIRS}) -endif() - -find_library(SOUP_LIBRARIES - NAMES soup-2.4 - HINTS ${_SOUP_ROOT_PATHS} - PATH_SUFFIXES bin lib -) - -if(SOUP_LIBRARIES) - list(APPEND SOUP_LIBRARIES ${GTK2_LIBRARIES}) -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Soup - DEFAULT_MSG - SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H -) - -mark_as_advanced(SOUP_INCLUDE_DIRS SOUP_LIBRARIES HAVE_LIBSOUP_SOUP_H) diff --git a/config.h.cmake b/config.h.cmake index 3adb3cae4..6d0015a20 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -37,7 +37,6 @@ #define PACKAGE_DATA_DIR "${PACKAGE_DATA_DIR}" #define PACKAGE_SOUND_DIR "${PACKAGE_SOUND_DIR}" -#cmakedefine BUILD_WIZARD #cmakedefine HAVE_NOTIFY4 #cmakedefine HAVE_ZLIB 1 #cmakedefine HAVE_CU_GET_SUITE 1 diff --git a/configure.ac b/configure.ac index 544691ff0..4ab84937d 100644 --- a/configure.ac +++ b/configure.ac @@ -729,43 +729,6 @@ if test "$has_sighandler_t" = "yes" ; then AC_DEFINE( HAVE_SIGHANDLER_T, 1, [Define if sighandler_t available] ) fi -AC_ARG_ENABLE(assistant, - [AS_HELP_STRING([--enable-assistant], [Turn on assistant compiling])], - [case "${enableval}" in - yes) build_wizard=true ;; - no) build_wizard=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-assistant) ;; - esac], - [build_wizard=check] -) - -dnl check libsoup (needed for wizard) -if test "$build_wizard" != "false" ; then - PKG_CHECK_MODULES(LIBSOUP, [libsoup-2.4 >= 2.26],[], - [if test "$build_wizard" = "true" ; then - AC_MSG_ERROR([Could not found libsoup, assistant cannot be compiled.]) - else - build_wizard=false - fi] - ) -fi -if test "$build_wizard" != "false" ; then - PKG_CHECK_MODULES(LIBGTKWIZARD, [gtk+-2.0 >= 2.22.0],[], - [if test "$build_wizard" = "true" ; then - AC_MSG_ERROR([gtk+-2.0 < 2.22.0, assistant cannot be compiled.]) - else - build_wizard=false - fi] - ) -fi -AC_SUBST(LIBSOUP_CFLAGS) -AC_SUBST(LIBSOUP_LIBS) -AM_CONDITIONAL(BUILD_WIZARD, test x$build_wizard != xfalse) -if test "$build_wizard" != "false" ; then - build_wizard=true - AC_DEFINE(BUILD_WIZARD, 1, [Define if wizard enabled] ) -fi - AC_CHECK_HEADERS(libudev.h) AC_CHECK_LIB(udev,udev_new) @@ -1074,7 +1037,6 @@ echo "Linphone build configuration ended." echo "Summary of build options:" printf "* %-30s %s\n" "Video support" $video printf "* %-30s %s\n" "GTK interface" $gtk_ui -printf "* %-30s %s\n" "Account assistant" $build_wizard printf "* %-30s %s\n" "Console interface" $console_ui printf "* %-30s %s\n" "Tools" $build_tools printf "* %-30s %s\n" "Message storage" $enable_msg_storage diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index b8b6b27cb..8b972bbcc 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -31,6 +31,8 @@ endif() set(SOURCE_FILES + account_creator.c + account_creator.h address.c authentication.c bellesip_sal/sal_address_impl.c @@ -92,6 +94,8 @@ set(SOURCE_FILES xml2lpc.c xml2lpc.h xml.c + xmlrpc.c + xmlrpc.h vtables.c ) if(ENABLE_TUNNEL) @@ -103,9 +107,6 @@ if(ENABLE_TUNNEL) else() list(APPEND SOURCE_FILES linphone_tunnel_stubs.c) endif() -if(ENABLE_ASSISTANT) - list(APPEND SOURCE_FILES sipwizard.c) -endif() set(GENERATED_SOURCE_FILES ${CMAKE_CURRENT_BINARY_DIR}/liblinphone_gitversion.h @@ -137,9 +138,6 @@ endif() if(ENABLE_TUNNEL) list(APPEND LIBS ${TUNNEL_LIBRARIES}) endif() -if(ENABLE_ASSISTANT) - list(APPEND LIBS ${SOUP_LIBRARIES}) -endif() if(MSVC AND NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsPhone") list(APPEND LIBS ${LIBGCC} ${LIBMINGWEX}) endif() diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 8582213c5..8130a8037 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -25,6 +25,7 @@ CLEANFILES=$(GITVERSION_FILE) linphone_includedir=$(includedir)/linphone linphone_include_HEADERS=\ + account_creator.h \ buffer.h \ call_log.h \ call_params.h \ @@ -38,11 +39,13 @@ linphone_include_HEADERS=\ lpc2xml.h \ lpconfig.h \ sipsetup.h \ - xml2lpc.h + xml2lpc.h \ + xmlrpc.h lib_LTLIBRARIES=liblinphone.la liblinphone_la_SOURCES=\ + account_creator.c \ address.c \ authentication.c \ buffer.c \ @@ -82,6 +85,7 @@ liblinphone_la_SOURCES=\ sipsetup.c sipsetup.h \ xml2lpc.c \ xml.c \ + xmlrpc.c \ vtables.c \ $(GITVERSION_FILE) @@ -102,10 +106,6 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \ bellesip_sal/sal_op_info.c \ bellesip_sal/sal_op_events.c -if BUILD_WIZARD -liblinphone_la_SOURCES+=sipwizard.c -endif - liblinphone_la_SOURCES+=linphone_tunnel_config.c if BUILD_TUNNEL liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh linphone_tunnel.h @@ -137,7 +137,6 @@ liblinphone_la_LIBADD= \ $(ORTP_LIBS) \ $(SIPSTACK_LIBS) \ $(TUNNEL_LIBS) \ - $(LIBSOUP_LIBS) \ $(SQLITE3_LIBS) \ $(LIBXML2_LIBS) \ $(LDAP_LIBS) \ @@ -170,7 +169,6 @@ COMMON_CFLAGS=\ $(STRICT_OPTIONS) \ -DIN_LINPHONE \ $(SIPSTACK_CFLAGS) \ - $(LIBSOUP_CFLAGS) \ -DENABLE_TRACE \ -DLOG_DOMAIN=\"LinphoneCore\" \ $(IPV6_CFLAGS) \ @@ -183,10 +181,6 @@ COMMON_CFLAGS=\ $(SASL_CFLAGS) \ $(ZLIB_CFLAGS) -if BUILD_WIZARD -COMMON_CFLAGS+= -DBUILD_WIZARD -endif - COMMON_CFLAGS+= -DUSE_BELLESIP AM_CFLAGS=$(COMMON_CFLAGS) $(STRICT_OPTIONS_CC) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c new file mode 100644 index 000000000..3ae286dbb --- /dev/null +++ b/coreapi/account_creator.c @@ -0,0 +1,256 @@ +/* +linphone +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +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. +*/ + +#include "linphonecore.h" +#include "private.h" + + +struct _LinphoneAccountCreator { + LinphoneXmlRpcSession *xmlrpc_session; + LinphoneAccountCreatorCb existence_test_cb; + LinphoneAccountCreatorCb validation_test_cb; + LinphoneAccountCreatorCb validate_cb; + LinphoneCore *core; + void *existence_test_cb_ud; + void *validation_test_cb_ud; + void *validate_cb_ud; + char *xmlrpc_url; + char *username; + char *password; + char *domain; + char *route; + char *email; + bool_t subscribe_to_newsletter; +}; + +LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url) { + LinphoneAccountCreator *creator; + creator = ms_new0(LinphoneAccountCreator, 1); + creator->core = core; + creator->xmlrpc_session = linphone_xml_rpc_session_new(core, xmlrpc_url); + return creator; +} + +void linphone_account_creator_set_username(LinphoneAccountCreator *creator, const char *username) { + set_string(&creator->username, username); +} + +const char * linphone_account_creator_get_username(const LinphoneAccountCreator *creator) { + return creator->username; +} + +void linphone_account_creator_set_password(LinphoneAccountCreator *creator, const char *password){ + set_string(&creator->password, password); +} + +const char * linphone_account_creator_get_password(const LinphoneAccountCreator *creator) { + return creator->password; +} + +void linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain){ + set_string(&creator->domain, domain); +} + +const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator) { + return creator->domain; +} + +void linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route) { + set_string(&creator->route, route); +} + +const char * linphone_account_creator_get_route(const LinphoneAccountCreator *creator) { + return creator->route; +} + +void linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email) { + set_string(&creator->email, email); +} + +const char * linphone_account_creator_get_email(const LinphoneAccountCreator *creator) { + return creator->email; +} + +void linphone_account_creator_enable_newsletter_subscription(LinphoneAccountCreator *creator, bool_t subscribe) { + creator->subscribe_to_newsletter = subscribe; +} + +bool_t linphone_account_creator_newsletter_subscription_enabled(const LinphoneAccountCreator *creator) { + return creator->subscribe_to_newsletter; +} + +void linphone_account_creator_set_test_existence_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data) { + creator->existence_test_cb = cb; + creator->existence_test_cb_ud = user_data; +} + +void linphone_account_creator_set_test_validation_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data) { + creator->validation_test_cb = cb; + creator->validation_test_cb_ud = user_data; +} + +void linphone_account_creator_set_validate_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data) { + creator->validate_cb = cb; + creator->validate_cb_ud = user_data; +} + +static void _test_existence_cb(LinphoneXmlRpcRequest *request, void *user_data) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)user_data; + if (creator->existence_test_cb != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorFailed; + if ((linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) + && (linphone_xml_rpc_request_get_int_response(request) == 0)) { + status = LinphoneAccountCreatorOk; + } + creator->existence_test_cb(creator, status, creator->existence_test_cb_ud); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_test_existence(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain) return LinphoneAccountCreatorFailed; + + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("check_account", LinphoneXmlRpcArgInt, + _test_existence_cb, creator, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOk; +} + +static void _test_validation_cb(LinphoneXmlRpcRequest *request, void *user_data) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)user_data; + if (creator->validation_test_cb != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorFailed; + if ((linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) + && (linphone_xml_rpc_request_get_int_response(request) == 1)) { + status = LinphoneAccountCreatorOk; + } + creator->validation_test_cb(creator, status, creator->validation_test_cb_ud); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_test_validation(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain) return LinphoneAccountCreatorFailed; + + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("check_account_validated", LinphoneXmlRpcArgInt, + _test_validation_cb, creator, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOk; +} + +static void _validate_cb(LinphoneXmlRpcRequest *request, void *user_data) { + LinphoneAccountCreator *creator = (LinphoneAccountCreator *)user_data; + if (creator->validate_cb != NULL) { + LinphoneAccountCreatorStatus status = LinphoneAccountCreatorFailed; + if ((linphone_xml_rpc_request_get_status(request) == LinphoneXmlRpcStatusOk) + && (linphone_xml_rpc_request_get_int_response(request) == 0)) { + status = LinphoneAccountCreatorOk; + } + creator->validate_cb(creator, status, creator->validate_cb_ud); + } +} + +LinphoneAccountCreatorStatus linphone_account_creator_validate(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + char *identity; + + if (!creator->username || !creator->domain) return LinphoneAccountCreatorFailed; + + identity = ms_strdup_printf("%s@%s", creator->username, creator->domain); + request = linphone_xml_rpc_request_new_with_args("create_account", LinphoneXmlRpcArgInt, + _validate_cb, creator, + LinphoneXmlRpcArgString, identity, + LinphoneXmlRpcArgString, creator->password, + LinphoneXmlRpcArgString, creator->email, + LinphoneXmlRpcArgInt, (creator->subscribe_to_newsletter == TRUE) ? 1 : 0, + LinphoneXmlRpcArgNone); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + ms_free(identity); + return LinphoneAccountCreatorOk; +} + +LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator) { + LinphoneAddress *identity; + LinphoneAuthInfo *info; + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); + char *identity_str = ms_strdup_printf("sip:%s@%s", creator->username, creator->domain); + + linphone_proxy_config_set_identity(cfg, identity_str); + linphone_proxy_config_set_server_addr(cfg, creator->domain); + linphone_proxy_config_set_route(cfg, creator->route); + linphone_proxy_config_enable_publish(cfg, FALSE); + linphone_proxy_config_enable_register(cfg, TRUE); + ms_free(identity_str); + + if (strcmp(creator->domain, "sip.linphone.org") == 0) { + linphone_proxy_config_enable_avpf(cfg, TRUE); + // If account created on sip.linphone.org, we configure linphone to use TLS by default + if (linphone_core_sip_transport_supported(creator->core, LinphoneTransportTls)) { + LinphoneAddress *addr = linphone_address_new(linphone_proxy_config_get_server_addr(cfg)); + char *tmp; + linphone_address_set_transport(addr, LinphoneTransportTls); + tmp = linphone_address_as_string(addr); + linphone_proxy_config_set_server_addr(cfg, tmp); + linphone_proxy_config_set_route(cfg, tmp); + ms_free(tmp); + linphone_address_destroy(addr); + } + linphone_core_set_stun_server(creator->core, "stun.linphone.org"); + linphone_core_set_firewall_policy(creator->core, LinphonePolicyUseIce); + } + + identity = linphone_address_new(linphone_proxy_config_get_identity(cfg)); + info = linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity)); + linphone_core_add_auth_info(creator->core, info); + linphone_address_destroy(identity); + + if (linphone_core_add_proxy_config(creator->core, cfg) != -1) { + linphone_core_set_default_proxy(creator->core, cfg); + return cfg; + } + + linphone_core_remove_auth_info(creator->core, info); + linphone_proxy_config_unref(cfg); + return NULL; +} + +void linphone_account_creator_destroy(LinphoneAccountCreator *creator){ + linphone_xml_rpc_session_unref(creator->xmlrpc_session); + if (creator->username) ms_free(creator->username); + if (creator->password) ms_free(creator->password); + if (creator->domain) ms_free(creator->domain); + if (creator->route) ms_free(creator->route); + if (creator->email) ms_free(creator->email); + ms_free(creator); +} diff --git a/coreapi/account_creator.h b/coreapi/account_creator.h new file mode 100644 index 000000000..582b6d3bf --- /dev/null +++ b/coreapi/account_creator.h @@ -0,0 +1,215 @@ +/* +account_creator.h +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +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. +*/ + +#ifndef LINPHONE_ACCOUNT_CREATOR_H_ +#define LINPHONE_ACCOUNT_CREATOR_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup misc + * @{ + */ + +/** +* Enum describing the status of a LinphoneAccountCreator operation. +**/ +typedef enum _LinphoneAccountCreatorStatus { + LinphoneAccountCreatorOk, + LinphoneAccountCreatorFailed +} LinphoneAccountCreatorStatus; + +/** + * The LinphoneAccountCreator object used to create an account on a server via XML-RPC. +**/ +typedef struct _LinphoneAccountCreator LinphoneAccountCreator; + +/** + * Callback used to notify the end of a LinphoneAccountCreator operation. + * @param[in] creator LinphoneAccountCreator object + * @param[in] status The status of the LinphoneAccountCreator operation that has just finished + * @param user_data A user data given when setting the callback. +**/ +typedef void (*LinphoneAccountCreatorCb)(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, void *user_data); + +/** + * Create a LinphoneAccountCreator. + * @param[in] core The LinphoneCore used for the XML-RPC communication + * @param[in] xmlrpc_url The URL to the XML-RPC server + * @return The new LinphoneAccountCreator object +**/ +LINPHONE_PUBLIC LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url); + +/** + * Destroy a LinphoneAccountCreator. + * @param[in] creator LinphoneAccountCreator object + * @param +**/ +LINPHONE_PUBLIC void linphone_account_creator_destroy(LinphoneAccountCreator *creator); + +/** + * Set the username. + * @param[in] creator LinphoneAccountCreator object + * @param[in] username The username to set +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_username(LinphoneAccountCreator *creator, const char *username); + +/** + * Get the username. + * @param[in] creator LinphoneAccountCreator object + * @return The username of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_username(const LinphoneAccountCreator *creator); + +/** + * Set the password. + * @param[in] creator LinphoneAccountCreator object + * @param[in] password The password to set +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_password(LinphoneAccountCreator *creator, const char *password); + +/** + * Get the password. + * @param[in] creator LinphoneAccountCreator object + * @return The password of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_password(const LinphoneAccountCreator *creator); + +/** + * Set the domain. + * @param[in] creator LinphoneAccountCreator object + * @param[in] domain The domain to set +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); + +/** + * Get the domain. + * @param[in] creator LinphoneAccountCreator object + * @return The domain of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator); + +/** + * Set the route. + * @param[in] creator LinphoneAccountCreator object + * @param[in] route The route to set +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route); + +/** + * Get the route. + * @param[in] creator LinphoneAccountCreator object + * @return The route of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_route(const LinphoneAccountCreator *creator); + +/** + * Set the email. + * @param[in] creator LinphoneAccountCreator object + * @param[in] email The email to set +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_email(LinphoneAccountCreator *creator, const char *email); + +/** + * Get the email. + * @param[in] creator LinphoneAccountCreator object + * @return The email of the LinphoneAccountCreator +**/ +LINPHONE_PUBLIC const char * linphone_account_creator_get_email(const LinphoneAccountCreator *creator); + +/** + * Enable the newsletter subscription. + * @param[in] creator LinphoneAccountCreator object + * @param[in] subscribe A boolean telling whether to subscribe to the newsletter or not. +**/ +LINPHONE_PUBLIC void linphone_account_creator_enable_newsletter_subscription(LinphoneAccountCreator *creator, bool_t subscribe); + +/** + * Tell whether to subscribe to the newsletter or not. + * @param[in] creator LinphoneAccountCreator object + * @return A boolean telling whether to subscribe to the newsletter or not. +**/ +LINPHONE_PUBLIC bool_t linphone_account_creator_newsletter_subscription_enabled(const LinphoneAccountCreator *creator); + +/** + * Set the callback called when the account existence test is finished. + * @param[in] creator LinphoneAccountCreator object + * @param[in] cb The callback called when the account existence test is finished + * @param[in] user_data The user data passed to the callback +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_test_existence_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data); + +/** + * Set the callback called when the account validation test is finished. + * @param[in] creator LinphoneAccountCreator object + * @param[in] cb The callback called when the account validation test is finished + * @param[in] user_data The user data passed to the callback +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_test_validation_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data); + +/** + * Set the callback called when the account creation is finished. + * @param[in] creator LinphoneAccountCreator object + * @param[in] cb The callback called when the account creation is finished + * @param[in] user_data The user data passed to the callback +**/ +LINPHONE_PUBLIC void linphone_account_creator_set_validate_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorCb cb, void *user_data); + +/** + * Send an XML-RPC request to test the existence of a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_test_existence(LinphoneAccountCreator *creator); + +/** + * Send an XML-RPC request to test the validation of a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_test_validation(LinphoneAccountCreator *creator); + +/** + * Send an XML-RPC request to create a Linphone account. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorOk if the request has been sent, LinphoneAccountCreatorFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_validate(LinphoneAccountCreator *creator); + +/** + * Configure an account (create a proxy config and authentication info for it). + * @param[in] creator LinphoneAccountCreator object + * @return A LinphoneProxyConfig object if successful, NULL otherwise +**/ +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LINPHONE_ACCOUNT_CREATOR_H_ */ diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index cec387e66..47bc7fcc6 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -373,6 +373,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "content.h" #include "event.h" #include "linphonefriend.h" +#include "xmlrpc.h" #else #include "linphone/buffer.h" #include "linphone/call_log.h" @@ -380,6 +381,7 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "linphone/content.h" #include "linphone/event.h" #include "linphone/linphonefriend.h" +#include "linphone/xmlrpc.h" #endif LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr); @@ -1177,32 +1179,6 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_custom_header(LinphoneProxyConfig * @} **/ -typedef struct _LinphoneAccountCreator{ - LinphoneCore *lc; - struct _SipSetupContext *ssctx; - char *username; - char *password; - char *domain; - char *route; - char *email; - int suscribe; - bool_t succeeded; -}LinphoneAccountCreator; - -LINPHONE_PUBLIC LinphoneAccountCreator *linphone_account_creator_new(LinphoneCore *core, const char *type); -LINPHONE_PUBLIC void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username); -LINPHONE_PUBLIC void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password); -LINPHONE_PUBLIC void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain); -LINPHONE_PUBLIC void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route); -LINPHONE_PUBLIC void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email); -LINPHONE_PUBLIC void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribre); -LINPHONE_PUBLIC const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj); -LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj); -LINPHONE_PUBLIC int linphone_account_creator_test_existence(LinphoneAccountCreator *obj); -LINPHONE_PUBLIC int linphone_account_creator_test_validation(LinphoneAccountCreator *obj); -LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj); -LINPHONE_PUBLIC void linphone_account_creator_destroy(LinphoneAccountCreator *obj); - struct _LinphoneAuthInfo; /** @@ -1358,6 +1334,13 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon */ +#ifdef IN_LINPHONE +#include "account_creator.h" +#else +#include "linphone/account_creator.h" +#endif + + struct _LinphoneChatRoom; /** * @addtogroup chatroom diff --git a/coreapi/private.h b/coreapi/private.h index f79875697..09b82c704 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -979,6 +979,42 @@ struct _LinphoneBuffer { BELLE_SIP_DECLARE_VPTR(LinphoneBuffer); +/***************************************************************************** + * XML-RPC interface * + ****************************************************************************/ + +typedef struct _LinphoneXmlRpcArg { + LinphoneXmlRpcArgType type; + union { + int i; + char *s; + } data; +} LinphoneXmlRpcArg; + +struct _LinphoneXmlRpcRequest { + belle_sip_object_t base; + void *user_data; + belle_sip_list_t *arg_list; + char *content; /**< The string representation of the XML-RPC request */ + char *method; + LinphoneXmlRpcResponseCb cb; + void *cb_ud; + LinphoneXmlRpcStatus status; + LinphoneXmlRpcArg response; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcRequest); + +struct _LinphoneXmlRpcSession { + belle_sip_object_t base; + void *user_data; + LinphoneCore *core; + char *url; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneXmlRpcSession); + + /***************************************************************************** * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ @@ -1083,7 +1119,9 @@ BELLE_SIP_TYPE_ID(LinphoneContent), BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider), BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch), BELLE_SIP_TYPE_ID(LinphoneProxyConfig), -BELLE_SIP_TYPE_ID(LinphoneFriend) +BELLE_SIP_TYPE_ID(LinphoneFriend), +BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), +BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/proxy.c b/coreapi/proxy.c index ab66caa1d..61ab697d0 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -1504,98 +1504,6 @@ SipSetupContext *linphone_proxy_config_get_sip_setup_context(LinphoneProxyConfig * @} **/ -LinphoneAccountCreator *linphone_account_creator_new(struct _LinphoneCore *core, const char *type){ - LinphoneAccountCreator *obj; - LinphoneProxyConfig *cfg; - SipSetup *ss=sip_setup_lookup(type); - SipSetupContext *ssctx; - if (!ss){ - return NULL; - } - if (!(sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER)){ - ms_error("%s cannot manage accounts.",type); - return NULL; - } - obj=ms_new0(LinphoneAccountCreator,1); - cfg=linphone_proxy_config_new(); - ssctx=sip_setup_context_new(ss,cfg); - obj->lc=core; - obj->ssctx=ssctx; - set_string(&obj->domain,sip_setup_context_get_domains(ssctx)[0]); - cfg->lc=core; - return obj; -} - -void linphone_account_creator_set_username(LinphoneAccountCreator *obj, const char *username){ - set_string(&obj->username,username); -} - -void linphone_account_creator_set_password(LinphoneAccountCreator *obj, const char *password){ - set_string(&obj->password,password); -} - -void linphone_account_creator_set_domain(LinphoneAccountCreator *obj, const char *domain){ - set_string(&obj->domain,domain); -} - -void linphone_account_creator_set_route(LinphoneAccountCreator *obj, const char *route) { - set_string(&obj->route,route); -} - -void linphone_account_creator_set_email(LinphoneAccountCreator *obj, const char *email) { - set_string(&obj->email,email); -} - -void linphone_account_creator_set_suscribe(LinphoneAccountCreator *obj, int suscribe) { - obj->suscribe = suscribe; -} - -const char * linphone_account_creator_get_username(LinphoneAccountCreator *obj){ - return obj->username; -} - -const char * linphone_account_creator_get_domain(LinphoneAccountCreator *obj){ - return obj->domain; -} - -int linphone_account_creator_test_existence(LinphoneAccountCreator *obj){ - SipSetupContext *ssctx=obj->ssctx; - char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain); - int err=sip_setup_context_account_exists(ssctx,uri); - ms_free(uri); - return err; -} - -int linphone_account_creator_test_validation(LinphoneAccountCreator *obj) { - SipSetupContext *ssctx=obj->ssctx; - int err=sip_setup_context_account_validated(ssctx,obj->username); - return err; -} - -LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj){ - SipSetupContext *ssctx=obj->ssctx; - char *uri=ms_strdup_printf("%s@%s",obj->username,obj->domain); - int err=sip_setup_context_create_account(ssctx, uri, obj->password, obj->email, obj->suscribe); - ms_free(uri); - if (err==0) { - obj->succeeded=TRUE; - return sip_setup_context_get_proxy_config(ssctx); - } - return NULL; -} - -void linphone_account_creator_destroy(LinphoneAccountCreator *obj){ - if (obj->username) - ms_free(obj->username); - if (obj->password) - ms_free(obj->password); - if (obj->domain) - ms_free(obj->domain); - if (!obj->succeeded){ - linphone_proxy_config_destroy(sip_setup_context_get_proxy_config(obj->ssctx)); - } -} - void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud) { cfg->user_data = ud; } diff --git a/coreapi/sipsetup.c b/coreapi/sipsetup.c index bf1b411e8..7c9f074d9 100644 --- a/coreapi/sipsetup.c +++ b/coreapi/sipsetup.c @@ -24,14 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" extern SipSetup linphone_sip_login; -#ifdef BUILD_WIZARD -extern SipSetup linphone_sip_wizard; -#endif static SipSetup *all_sip_setups[]={ &linphone_sip_login, -#ifdef BUILD_WIZARD - &linphone_sip_wizard, -#endif NULL }; diff --git a/coreapi/sipsetup.h b/coreapi/sipsetup.h index 2cbe24036..63d71d5f1 100644 --- a/coreapi/sipsetup.h +++ b/coreapi/sipsetup.h @@ -31,10 +31,13 @@ struct _SipSetup; struct _BuddyInfo; +struct _LinphoneXmlRpcSession; + struct _SipSetupContext{ struct _SipSetup *funcs; struct _LinphoneProxyConfig *cfg; + struct _LinphoneXmlRpcSession *xmlrpc_session; char domain[128]; char username[128]; void *data; diff --git a/coreapi/sipwizard.c b/coreapi/sipwizard.c deleted file mode 100644 index 879b9942a..000000000 --- a/coreapi/sipwizard.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -sipwizard.c -Copyright (C) 2011 Belledonne Communication, Grenoble, France - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -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. -*/ - -#include "linphonecore.h" -#include "private.h" -#include -#include - -typedef struct _BLReq{ - int status; - int result; - SoupMessage *msg; - SoupSession *session; - ortp_thread_t th; -}BLReq; - -static const int XMLRPC_FAILED = -1; -static const int XMLRPC_OK = 0; -static const char *XMLRPC_URL = "https://www.linphone.org/wizard.php"; - -static void sip_wizard_init_instance(SipSetupContext *ctx){ - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - /*disable registration until the user logs in*/ - linphone_proxy_config_enable_register(cfg,FALSE); -} - -static const char ** sip_wizard_get_domains(SipSetupContext *ctx) { - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - const char **domains = (const char**) &cfg->reg_proxy; - return domains; -} - - -static int xml_rpc_parse_response(BLReq *blreq, SoupMessage *sm){ - SoupBuffer *sb; - GValue retval; - GError *error=NULL; - sb=soup_message_body_flatten(sm->response_body); - ms_message("This the xml-rpc response:\n%s\n",sb->data); - if (soup_xmlrpc_parse_method_response(sb->data,sb->length,&retval,&error)==FALSE){ - if (error!=NULL){ - ms_error("xmlrpc fault: %s",error->message); - g_error_free(error); - }else{ - ms_error("Could not parse xml-rpc response !"); - } - blreq->status=XMLRPC_FAILED; - }else{ - ms_message("Extracting values from return type..."); - blreq->result = g_value_get_int(&retval); - g_value_unset(&retval); - blreq->status=XMLRPC_OK; - } - soup_buffer_free(sb); - return blreq->status; -} - -static void got_headers(BLReq *blreq, SoupMessage*msg){ - ms_message("Got headers !"); - blreq->status=XMLRPC_OK; -} - -#if SERIALIZE_HTTPS -/*on windows libsoup support for threads with gnutls is not yet functionnal (only in git) -This will come in next release of libsoup, probably. -In the meantime, we are forced to serialize all soup https processing with a big -ugly global mutex...*/ - -static GStaticMutex big_mutex = G_STATIC_MUTEX_INIT; -#endif - -static void * process_xml_rpc_request(void *up){ - BLReq *blreq=(BLReq*)up; - SoupMessage *sm=blreq->msg; - int code; - g_signal_connect_swapped(G_OBJECT(sm),"got-headers",(GCallback)got_headers,blreq); - blreq->status=XMLRPC_OK; -#if SERIALIZE_HTTPS - g_static_mutex_lock(&big_mutex); -#endif - code=soup_session_send_message(blreq->session,sm); - if (code==200){ - xml_rpc_parse_response(blreq,sm); - }else{ - ms_error("request failed, error-code=%i (%s)",code,soup_status_get_phrase(code)); - blreq->status=XMLRPC_FAILED; - } -#if SERIALIZE_HTTPS - g_static_mutex_unlock(&big_mutex); -#endif - return NULL; -} - - -static int do_simple_xmlrpc_request(SoupMessage *msg) { - int ret=-1; - BLReq *req; - - if (!msg){ - ms_error("Fail to create SoupMessage !"); - return -1; - }else{ - SoupBuffer *sb=soup_message_body_flatten(msg->request_body); - ms_message("This is the XML-RPC request we are going to send:\n%s\n",sb->data); - soup_buffer_free(sb); - } - - req=ms_new0(BLReq, 1); - req->session=soup_session_sync_new(); - req->msg=msg; - - process_xml_rpc_request(req); - - if (req->status == XMLRPC_OK) { - ret=req->result; - } - - // Freeing allocated structures lead to a crash (why?) - //g_free(req->session); - //g_free(msg); - ms_free(req); - - return ret; -} - -/* - * Return 1 if account already exists - * 0 if account doesn't exists - * -1 if information isn't available - */ -static int sip_wizard_account_exists(SipSetupContext *ctx, const char *identity) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "check_account", - G_TYPE_STRING, identity, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static int sip_wizard_account_validated(SipSetupContext *ctx, const char *identity) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "check_account_validated", - G_TYPE_STRING, identity, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static int sip_wizard_create_account(SipSetupContext *ctx, const char *identity, const char *passwd, const char *email, int suscribe) { - SoupMessage *msg=soup_xmlrpc_request_new(XMLRPC_URL, - "create_account", - G_TYPE_STRING, identity, - G_TYPE_STRING, passwd, - G_TYPE_STRING, email, - G_TYPE_INT, suscribe, - G_TYPE_INVALID); - return do_simple_xmlrpc_request(msg); -} - -static void guess_display_name(LinphoneAddress *from){ - const char *username=linphone_address_get_username(from); - char *dn=(char*)ms_malloc(strlen(username)+1); - const char *it; - char *wptr=dn; - bool_t begin=TRUE; - bool_t surname=FALSE; - for(it=username;*it!='\0';++it){ - if (begin){ - *wptr=toupper(*it); - begin=FALSE; - }else if (*it=='.'){ - if (surname) break; - *wptr=' '; - begin=TRUE; - surname=TRUE; - }else { - *wptr=*it; - } - wptr++; - } - *wptr='\0'; - linphone_address_set_display_name(from,dn); - ms_free(dn); -} - -static int sip_wizard_do_login(SipSetupContext * ctx, const char *uri, const char *passwd, const char *userid){ - LinphoneProxyConfig *cfg=sip_setup_context_get_proxy_config(ctx); - LinphoneCore *lc=linphone_proxy_config_get_core(cfg); - LinphoneAuthInfo *auth; - LinphoneAddress *parsed_uri; - char *tmp; - - parsed_uri=linphone_address_new(uri); - if (parsed_uri==NULL){ - return -1; - } - if (linphone_address_get_display_name(parsed_uri)!=NULL){ - guess_display_name(parsed_uri); - } - tmp=linphone_address_as_string(parsed_uri); - linphone_proxy_config_set_identity(cfg,tmp); - if (passwd) { - auth=linphone_auth_info_new(linphone_address_get_username(parsed_uri),NULL,passwd,NULL,NULL,NULL); - linphone_core_add_auth_info(lc,auth); - } - linphone_proxy_config_enable_register(cfg,TRUE); - linphone_proxy_config_done(cfg); - ms_free(tmp); - linphone_address_destroy(parsed_uri); - return 0; -} - -/* a simple SipSetup built-in plugin to allow creating accounts at runtime*/ - -#ifndef _MSC_VER - -SipSetup linphone_sip_wizard={ - .name="SipWizard", - .capabilities=SIP_SETUP_CAP_ACCOUNT_MANAGER, - .init_instance=sip_wizard_init_instance, - .account_exists=sip_wizard_account_exists, - .create_account=sip_wizard_create_account, - .login_account=sip_wizard_do_login, - .get_domains=sip_wizard_get_domains, - .account_validated=sip_wizard_account_validated -}; - -#else -SipSetup linphone_sip_wizard={ - "SipWizard", - SIP_SETUP_CAP_ACCOUNT_MANAGER, - 0, - NULL, - NULL, - sip_wizard_init_instance, - NULL, - sip_wizard_account_exists, - sip_wizard_create_account, - sip_wizard_do_login, - NULL, - NULL, - NULL, - NULL, - sip_wizard_get_domains, - NULL, - NULL, - sip_wizard_account_validated -}; - - - -#endif diff --git a/coreapi/xmlrpc.c b/coreapi/xmlrpc.c new file mode 100644 index 000000000..61a6566d1 --- /dev/null +++ b/coreapi/xmlrpc.c @@ -0,0 +1,379 @@ +/* +linphone +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +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. +*/ + +#include "linphonecore.h" +#include "private.h" + +#include +#include +#include + + + +static void format_request(LinphoneXmlRpcRequest *request) { + char si[64]; + belle_sip_list_t *arg_ptr = request->arg_list; + xmlBufferPtr buf; + xmlTextWriterPtr writer; + int err; + + if (request->content != NULL) { + belle_sip_free(request->content); + request->content = NULL; + } + + buf = xmlBufferCreate(); + if (buf == NULL) { + ms_error("Error creating the XML buffer"); + return; + } + writer = xmlNewTextWriterMemory(buf, 0); + if (writer == NULL) { + ms_error("Error creating the XML writer"); + return; + } + + err = xmlTextWriterStartDocument(writer, "1.0", "UTF-8", NULL); + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"methodCall"); + } + if (err >= 0) { + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"methodName", (const xmlChar *)request->method); + } + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"params"); + } + while (arg_ptr != NULL) { + LinphoneXmlRpcArg *arg = (LinphoneXmlRpcArg *)arg_ptr->data; + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"param"); + } + if (err >= 0) { + err = xmlTextWriterStartElement(writer, (const xmlChar *)"value"); + } + switch (arg->type) { + case LinphoneXmlRpcArgNone: + break; + case LinphoneXmlRpcArgInt: + memset(si, 0, sizeof(si)); + snprintf(si, sizeof(si), "%i", arg->data.i); + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"int", (const xmlChar *)si); + break; + case LinphoneXmlRpcArgString: + err = xmlTextWriterWriteElement(writer, (const xmlChar *)"string", (const xmlChar *)arg->data.s); + break; + } + if (err >= 0) { + /* Close the "value" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + /* Close the "param" element. */ + err = xmlTextWriterEndElement(writer); + } + arg_ptr = arg_ptr->next; + } + if (err >= 0) { + /* Close the "params" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + /* Close the "methodCall" element. */ + err = xmlTextWriterEndElement(writer); + } + if (err >= 0) { + err = xmlTextWriterEndDocument(writer); + } + if (err > 0) { + /* xmlTextWriterEndDocument returns the size of the content. */ + request->content = belle_sip_strdup((const char *)buf->content); + } + xmlFreeTextWriter(writer); + xmlBufferFree(buf); +} + +static void free_arg(LinphoneXmlRpcArg *arg) { + if ((arg->type == LinphoneXmlRpcArgString) && (arg->data.s != NULL)) { + belle_sip_free(arg->data.s); + } + belle_sip_free(arg); +} + +static void process_io_error_from_post_xml_rpc_request(void *data, const belle_sip_io_error_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + ms_error("I/O Error during XML-RPC request sending"); + request->status = LinphoneXmlRpcStatusFailed; + if (request->cb != NULL) { + request->cb(request, request->cb_ud); + } + linphone_xml_rpc_request_unref(request); +} + +static void process_auth_requested_from_post_xml_rpc_request(void *data, belle_sip_auth_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + ms_error("Authentication error during XML-RPC request sending"); + request->status = LinphoneXmlRpcStatusFailed; + if (request->cb != NULL) { + request->cb(request, request->cb_ud); + } + linphone_xml_rpc_request_unref(request); +} + +static void parse_valid_xml_rpc_response(LinphoneXmlRpcRequest *request, const char *response_body) { + xmlparsing_context_t *xml_ctx = linphone_xmlparsing_context_new(); + xmlSetGenericErrorFunc(xml_ctx, linphone_xmlparsing_genericxml_error); + request->status = LinphoneXmlRpcStatusFailed; + xml_ctx->doc = xmlReadDoc((const unsigned char*)response_body, 0, NULL, 0); + if (xml_ctx->doc != NULL) { + const char *response_str; + if (linphone_create_xml_xpath_context(xml_ctx) < 0) goto end; + switch (request->response.type) { + case LinphoneXmlRpcArgInt: + response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/int"); + if (response_str != NULL) { + request->response.data.i = atoi(response_str); + request->status = LinphoneXmlRpcStatusOk; + } + break; + case LinphoneXmlRpcArgString: + response_str = linphone_get_xml_text_content(xml_ctx, "/methodResponse/params/param/value/string"); + if (response_str != NULL) { + request->response.data.s = belle_sip_strdup(response_str); + request->status = LinphoneXmlRpcStatusOk; + } + break; + default: + break; + } + linphone_free_xml_text_content(response_str); + } else { + ms_warning("Wrongly formatted XML-RPC response: %s", xml_ctx->errorBuffer); + } +end: + linphone_xmlparsing_context_destroy(xml_ctx); + if (request->cb != NULL) { + request->cb(request, request->cb_ud); + } +} + +static void notify_xml_rpc_error(LinphoneXmlRpcRequest *request) { + request->status = LinphoneXmlRpcStatusOk; + if (request->cb != NULL) { + request->cb(request, request->cb_ud); + } +} + +static void process_response_from_post_xml_rpc_request(void *data, const belle_http_response_event_t *event) { + LinphoneXmlRpcRequest *request = (LinphoneXmlRpcRequest *)data; + + /* Check the answer code */ + if (event->response) { + int code = belle_http_response_get_status_code(event->response); + if (code == 200) { /* Valid response from the server. */ + parse_valid_xml_rpc_response(request, belle_sip_message_get_body((belle_sip_message_t *)event->response)); + } else { + notify_xml_rpc_error(request); + } + } + linphone_xml_rpc_request_unref(request); +} + + +static LinphoneXmlRpcRequest * _linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type, LinphoneXmlRpcResponseCb cb, void *user_data) { + LinphoneXmlRpcRequest *request = belle_sip_object_new(LinphoneXmlRpcRequest); + belle_sip_object_ref(request); + request->status = LinphoneXmlRpcStatusPending; + request->response.type = return_type; + request->method = belle_sip_strdup(method); + request->cb = cb; + request->cb_ud = user_data; + return request; +} + +static void _linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) { + LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg)); + arg->type = LinphoneXmlRpcArgInt; + arg->data.i = value; + request->arg_list = belle_sip_list_append(request->arg_list, arg); +} + +static void _linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) { + LinphoneXmlRpcArg *arg = belle_sip_malloc0(sizeof(LinphoneXmlRpcArg)); + arg->type = LinphoneXmlRpcArgString; + arg->data.s = belle_sip_strdup(value); + request->arg_list = belle_sip_list_append(request->arg_list, arg); +} + +static void _linphone_xml_rpc_request_destroy(LinphoneXmlRpcRequest *request) { + belle_sip_list_free_with_data(request->arg_list, (void (*)(void*))free_arg); + if ((request->response.type == LinphoneXmlRpcArgString) && (request->response.data.s != NULL)) { + belle_sip_free(request->response.data.s); + } + if (request->content) belle_sip_free(request->content); + belle_sip_free(request->method); +} + +static void _linphone_xml_rpc_session_destroy(LinphoneXmlRpcSession *session) { + belle_sip_free(session->url); +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcRequest); +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneXmlRpcSession); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcRequest, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_xml_rpc_request_destroy, + NULL, // clone + NULL, // marshal + TRUE +); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneXmlRpcSession, belle_sip_object_t, + (belle_sip_object_destroy_t)_linphone_xml_rpc_session_destroy, + NULL, // clone + NULL, // marshal + TRUE +); + + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type, LinphoneXmlRpcResponseCb cb, void *user_data) { + LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type, cb, user_data); + format_request(request); + return request; +} + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, LinphoneXmlRpcResponseCb cb, void *user_data, ...) { + bool_t cont = TRUE; + va_list args; + LinphoneXmlRpcArgType arg_type; + LinphoneXmlRpcRequest *request = _linphone_xml_rpc_request_new(method, return_type, cb, user_data); + va_start(args, cb); + while (cont) { + arg_type = va_arg(args, LinphoneXmlRpcArgType); + switch (arg_type) { + case LinphoneXmlRpcArgNone: + cont = FALSE; + break; + case LinphoneXmlRpcArgInt: + _linphone_xml_rpc_request_add_int_arg(request, va_arg(args, int)); + break; + case LinphoneXmlRpcArgString: + _linphone_xml_rpc_request_add_string_arg(request, va_arg(args, char *)); + break; + } + } + va_end(args); + format_request(request); + return request; +} + +LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request) { + belle_sip_object_ref(request); + return request; +} + +void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request) { + belle_sip_object_unref(request); +} + +void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request) { + return request->user_data; +} + +void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud) { + request->user_data = ud; +} + +void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value) { + _linphone_xml_rpc_request_add_int_arg(request, value); + format_request(request); +} + +void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value) { + _linphone_xml_rpc_request_add_string_arg(request, value); + format_request(request); +} + +const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request) { + return request->content; +} + +LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request) { + return request->status; +} + +int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request) { + return request->response.data.i; +} + +const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request) { + return request->response.data.s; +} + + +LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url) { + LinphoneXmlRpcSession *session = belle_sip_object_new(LinphoneXmlRpcSession); + belle_sip_object_ref(session); + session->core = core; + session->url = belle_sip_strdup(url); + return session; +} + +LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session) { + belle_sip_object_ref(session); + return session; +} + +void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session) { + belle_sip_object_unref(session); +} + +void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session) { + return session->user_data; +} + +void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud) { + session->user_data = ud; +} + +void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request) { + belle_http_request_listener_callbacks_t cbs = { 0 }; + belle_http_request_listener_t *l; + belle_generic_uri_t *uri; + belle_http_request_t *req; + belle_sip_memory_body_handler_t *bh; + const char *data; + LinphoneContent *content; + + linphone_xml_rpc_request_ref(request); + content = linphone_content_new(); + linphone_content_set_type(content, "text"); + linphone_content_set_subtype(content, "xml"); + linphone_content_set_string_buffer(content, linphone_xml_rpc_request_get_content(request)); + uri = belle_generic_uri_parse(session->url); + req = belle_http_request_create("POST", uri, belle_sip_header_content_type_create("text", "xml"), NULL); + data = linphone_xml_rpc_request_get_content(request); + bh = belle_sip_memory_body_handler_new_copy_from_buffer(data, strlen(data), NULL, NULL); + belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); + cbs.process_response = process_response_from_post_xml_rpc_request; + cbs.process_io_error = process_io_error_from_post_xml_rpc_request; + cbs.process_auth_requested = process_auth_requested_from_post_xml_rpc_request; + l = belle_http_request_listener_create_from_callbacks(&cbs, request); + belle_http_provider_send_request(session->core->http_provider, req, l); + linphone_content_unref(content); +} diff --git a/coreapi/xmlrpc.h b/coreapi/xmlrpc.h new file mode 100644 index 000000000..ce3dfe5bb --- /dev/null +++ b/coreapi/xmlrpc.h @@ -0,0 +1,212 @@ +/* +xmlrpc.h +Copyright (C) 2010-2015 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +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. +*/ + +#ifndef LINPHONE_XMLRPC_H_ +#define LINPHONE_XMLRPC_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup misc + * @{ + */ + +/** +* Enum describing the types of argument for LinphoneXmlRpcRequest. +**/ +typedef enum _LinphoneXmlRpcArgType { + LinphoneXmlRpcArgNone, + LinphoneXmlRpcArgInt, + LinphoneXmlRpcArgString +} LinphoneXmlRpcArgType; + +/** +* Enum describing the status of a LinphoneXmlRpcRequest. +**/ +typedef enum _LinphoneXmlRpcStatus { + LinphoneXmlRpcStatusPending, + LinphoneXmlRpcStatusOk, + LinphoneXmlRpcStatusFailed +} LinphoneXmlRpcStatus; + +/** + * The LinphoneXmlRpcRequest object representing a XML-RPC request to be sent. +**/ +typedef struct _LinphoneXmlRpcRequest LinphoneXmlRpcRequest; + +/** + * The LinphoneXmlRpcSession object used to send XML-RPC requests and handle their responses. +**/ +typedef struct _LinphoneXmlRpcSession LinphoneXmlRpcSession; + +/** + * Callback used to notify the response to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object + * @param[in] user_data A user data given when setting the callback upon creation of the XML-RPC request. +**/ +typedef void (*LinphoneXmlRpcResponseCb)(LinphoneXmlRpcRequest *request, void *user_data); + + +/** + * Create a new LinphoneXmlRpcRequest object. + * @param[in] method The XML-RPC method to call. + * @param[in] return_type The expected XML-RPC response type. + * @param[in] cb The callback that will be called when the XML-RPC response is received or if an error occurs. + * @param[in] user_data A user data that will be passed as a parameter to the callback. + * @return A new LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new(const char *method, LinphoneXmlRpcArgType return_type, + LinphoneXmlRpcResponseCb cb, void *user_data); + +/** + * Create a new LinphoneXmlRpcRequest object giving the arguments to the method call. + * @param[in] method The XML-RPC method to call. + * @param[in] return_type The expected XML-RPC response type. + * @param[in] cb The callback that will be called when the XML-RPC response is received or if an error occurs. + * @param[in] user_data A user data that will be passed as a parameter to the callback. + * @return A new LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_new_with_args(const char *method, LinphoneXmlRpcArgType return_type, + LinphoneXmlRpcResponseCb cb, void *user_data, ...); + +/** + * Acquire a reference to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The same LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcRequest * linphone_xml_rpc_request_ref(LinphoneXmlRpcRequest *request); + +/** + * Release reference to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_unref(LinphoneXmlRpcRequest *request); + +/** + * Retrieve the user pointer associated with the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The user pointer associated with the XML-RPC request. +**/ +LINPHONE_PUBLIC void *linphone_xml_rpc_request_get_user_data(const LinphoneXmlRpcRequest *request); + +/** + * Assign a user pointer to the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] ud The user pointer to associate with the XML-RPC request. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_set_user_data(LinphoneXmlRpcRequest *request, void *ud); + +/** + * Add an integer argument to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] value The integer value of the added argument. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_add_int_arg(LinphoneXmlRpcRequest *request, int value); + +/** + * Add a string argument to an XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @param[in] value The string value of the added argument. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_request_add_string_arg(LinphoneXmlRpcRequest *request, const char *value); + +/** + * Get the content of the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The string representation of the content of the XML-RPC request. + */ +LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_content(const LinphoneXmlRpcRequest *request); + +/** + * Get the status of the XML-RPC request. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The status of the XML-RPC request. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcStatus linphone_xml_rpc_request_get_status(const LinphoneXmlRpcRequest *request); + +/** + * Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning an integer response. + * @param[in] request LinphoneXmlRpcRequest object. + * @return The integer response to the XML-RPC request. +**/ +LINPHONE_PUBLIC int linphone_xml_rpc_request_get_int_response(const LinphoneXmlRpcRequest *request); + +/** +* Get the response to an XML-RPC request sent with linphone_xml_rpc_session_send_request() and returning a string response. +* @param[in] request LinphoneXmlRpcRequest object. +* @return The string response to the XML-RPC request. +**/ +LINPHONE_PUBLIC const char * linphone_xml_rpc_request_get_string_response(const LinphoneXmlRpcRequest *request); + +/** + * Create a new LinphoneXmlRpcSession object. + * @param[in] core The LinphoneCore object used to send the XML-RPC requests. + * @param[in] url The URL of the XML-RPC server to send the XML-RPC requests to. + * @return A new LinphoneXmlRpcSession object. + */ +LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_new(LinphoneCore *core, const char *url); + +/** + * Acquire a reference to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @return The same LinphoneXmlRpcSession object. +**/ +LINPHONE_PUBLIC LinphoneXmlRpcSession * linphone_xml_rpc_session_ref(LinphoneXmlRpcSession *session); + +/** + * Release reference to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_unref(LinphoneXmlRpcSession *session); + +/** + * Retrieve the user pointer associated with the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @return The user pointer associated with the XML-RPC session. +**/ +LINPHONE_PUBLIC void *linphone_xml_rpc_session_get_user_data(const LinphoneXmlRpcSession *session); + +/** + * Assign a user pointer to the XML-RPC session. + * @param[in] session LinphoneXmlRpcSession object. + * @param[in] ud The user pointer to associate with the XML-RPC session. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_set_user_data(LinphoneXmlRpcSession *session, void *ud); + +/** + * Send an XML-RPC request. + * @param[in] session LinphoneXmlRpcSession object. + * @param[in] request The LinphoneXmlRpcRequest to be sent. +**/ +LINPHONE_PUBLIC void linphone_xml_rpc_session_send_request(LinphoneXmlRpcSession *session, LinphoneXmlRpcRequest *request); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LINPHONE_XMLRPC_H_ */ diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt index 848a872b9..91ec2fdba 100644 --- a/gtk/CMakeLists.txt +++ b/gtk/CMakeLists.txt @@ -63,6 +63,7 @@ set(SOURCE_FILES loginframe.c main.c propertybox.c + setupwizard.c singleinstance.c status_icon.c status_notifier.c @@ -75,10 +76,6 @@ if(WIN32) list(APPEND SOURCE_FILES linphone.rc) endif() -if(ENABLE_ASSISTANT) - list(APPEND SOURCE_FILES setupwizard.c) -endif() - if(GETTEXT_FOUND) add_definitions("-DENABLE_NLS") endif() @@ -101,9 +98,6 @@ if(ENABLE_NOTIFY) target_include_directories(linphone-gtk PUBLIC ${NOTIFY_INCLUDE_DIRS}) target_link_libraries(linphone-gtk ${NOTIFY_LIBRARIES}) endif() -if(ENABLE_ASSISTANT) - target_link_libraries(linphone-gtk ${SOUP_LIBRARIES}) -endif() install(TARGETS linphone-gtk RUNTIME DESTINATION bin diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 32656c993..946de574b 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -53,6 +53,7 @@ linphone_SOURCES= \ singleinstance.c \ conference.c \ config-fetching.c \ + setupwizard.c \ audio_assistant.c \ videowindow.c \ status_icon.c status_icon.h \ @@ -64,11 +65,6 @@ linphone_SOURCES+= \ status_notifier.h endif -if BUILD_WIZARD -linphone_SOURCES+= \ - setupwizard.c -endif - linphone_LDADD= $(top_builddir)/coreapi/liblinphone.la \ $(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) $(SQLITE3_LIBS) $(BELLESIP_LIBS) diff --git a/gtk/main.c b/gtk/main.c index 2446473fb..99e464874 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1979,9 +1979,7 @@ static void linphone_gtk_check_soundcards(){ static void linphone_gtk_quit_core(void){ linphone_gtk_unmonitor_usb(); g_source_remove_by_user_data(linphone_gtk_get_core()); -#ifdef BUILD_WIZARD linphone_gtk_close_assistant(); -#endif linphone_gtk_set_ldap(NULL); linphone_gtk_destroy_log_window(); linphone_core_destroy(the_core); @@ -2021,12 +2019,10 @@ static gboolean on_block_termination(void){ static void linphone_gtk_init_ui(void){ linphone_gtk_init_main_window(); -#ifdef BUILD_WIZARD // Veryfing if at least one sip account is configured. If not, show wizard if (linphone_core_get_proxy_config_list(linphone_gtk_get_core()) == NULL) { linphone_gtk_show_assistant(the_ui); } -#endif if(run_audio_assistant){ linphone_gtk_show_audio_assistant(); diff --git a/gtk/main.ui b/gtk/main.ui index 48e5a61d6..df7bbc6e2 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -923,6 +923,7 @@ Account assistant + True False connect_image False diff --git a/gtk/password.ui b/gtk/password.ui index a355c1848..d9ce720aa 100644 --- a/gtk/password.ui +++ b/gtk/password.ui @@ -9,7 +9,6 @@ True center-on-parent dialog - False True diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 6f4816ece..ff0aa9baa 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -1584,11 +1584,6 @@ void linphone_gtk_show_parameters(void){ gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(pb,"username")),linphone_address_get_username(contact)); linphone_address_destroy(contact); } -#ifdef BUILD_WIZARD - gtk_widget_show(linphone_gtk_get_widget(pb,"wizard")); -#else - gtk_widget_hide(linphone_gtk_get_widget(pb,"wizard")); -#endif linphone_gtk_show_sip_accounts(pb); /* CODECS CONFIG */ linphone_gtk_init_codec_list(GTK_TREE_VIEW(codec_list)); diff --git a/gtk/setupwizard.c b/gtk/setupwizard.c index 96b12d50d..c2592535e 100644 --- a/gtk/setupwizard.c +++ b/gtk/setupwizard.c @@ -20,107 +20,199 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphone.h" #include #include -static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w); + static const int PASSWORD_MIN_SIZE = 6; static const int LOGIN_MIN_SIZE = 4; +static GtkWidget *the_assistant = NULL; -static GtkWidget *the_assistant=NULL; -static GtkWidget *create_intro(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(_("Welcome!\nThis assistant will help you to use a SIP account for your calls.")); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - g_object_set_data(G_OBJECT(vbox),"label",label); +static LinphoneAccountCreator * linphone_gtk_assistant_init(GtkWidget *w) { + LinphoneAccountCreator *creator = linphone_account_creator_new(linphone_gtk_get_core(), "https://www.linphone.org/wizard.php"); + g_object_set_data(G_OBJECT(w), "creator", creator); + return creator; +} + +static LinphoneAccountCreator * linphone_gtk_assistant_get_creator(GtkWidget *w) { + return (LinphoneAccountCreator *)g_object_get_data(G_OBJECT(w), "creator"); +} + +static void linphone_gtk_account_validate_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, void *user_data) { + GtkWidget *assistant = (GtkWidget *)user_data; + if (status == LinphoneAccountCreatorOk) { + // Go to page_6_linphone_account_validation_wait + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 6); + } else { // Error when attempting to create the account + // Go to page_8_error + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 8); + } + gtk_assistant_commit(GTK_ASSISTANT(assistant)); +} + +static void create_account(GtkWidget *assistant) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); + linphone_account_creator_set_validate_cb(creator, linphone_gtk_account_validate_cb, assistant); + linphone_account_creator_validate(creator); +} + +static void linphone_gtk_test_account_validation_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, void *user_data) { + GtkWidget *assistant = (GtkWidget *)user_data; + if (status == LinphoneAccountCreatorOk) { + // Go to page_9_finish + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 9); + } else { + // Go to page_8_error + gtk_assistant_set_current_page(GTK_ASSISTANT(assistant), 8); + } +} + +static void check_account_validation(GtkWidget *page) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); + linphone_account_creator_set_test_validation_cb(creator, linphone_gtk_test_account_validation_cb, page); + linphone_account_creator_test_validation(creator); +} + +static void linphone_gtk_assistant_closed(GtkWidget *w) { + linphone_gtk_close_assistant(); +} + +static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page) { + int pagenum = gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); + + switch (pagenum) { + case 5: + create_account(assistant); + break; + case 7: + check_account_validation(assistant); + break; + case 9: + if (linphone_account_creator_configure(linphone_gtk_assistant_get_creator(assistant)) != NULL) { + linphone_gtk_load_identities(); + } + gtk_assistant_commit(GTK_ASSISTANT(assistant)); + break; + default: + break; + } +} + +static gint destroy_assistant(GtkWidget* w){ + gtk_widget_destroy(w); + the_assistant = NULL; + return FALSE; +} + +static int linphone_gtk_assistant_forward(int curpage, gpointer data) { + GtkWidget *w = GTK_WIDGET(data); + GtkWidget *box = gtk_assistant_get_nth_page(GTK_ASSISTANT(w), curpage); + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(w); + + switch (curpage) { + case 0: + curpage = 1; // Go to page_1_choice + break; + case 1: + { + GtkWidget *create_button = (GtkWidget*)g_object_get_data(G_OBJECT(box), "create_account"); + GtkWidget *setup_linphone_account = (GtkWidget*)g_object_get_data(G_OBJECT(box), "setup_linphone_account"); + GtkWidget *setup_account = (GtkWidget*)g_object_get_data(G_OBJECT(box), "setup_account"); + GtkWidget *config_uri = (GtkWidget*)g_object_get_data(G_OBJECT(box), "config-uri"); + + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))) { + curpage = 4; // Go to page_4_linphone_account_creation_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_linphone_account))) { + curpage = 3; // Go to page_3_linphone_account_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_account))) { + curpage = 2; // Go to page_2_external_account_configuration + } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_uri))) { + /* Destroy the assistant and popup config-uri dialog */ + gtk_widget_hide(w); + linphone_gtk_set_configuration_uri(); + curpage = 0; + g_idle_add((GSourceFunc)destroy_assistant, w); + } + } + break; + case 2: + linphone_account_creator_set_username(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); + linphone_account_creator_set_domain(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); + linphone_account_creator_set_route(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "proxy")))); + linphone_account_creator_set_password(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "password")))); + curpage = 9; // Go to page_9_finish + break; + case 3: + linphone_account_creator_set_username(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); + linphone_account_creator_set_domain(creator, "sip.linphone.org"); + linphone_account_creator_set_route(creator, "sip.linphone.org"); + linphone_account_creator_set_password(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "password")))); + curpage = 9; // Go to page_9_finish + break; + case 4: + linphone_account_creator_set_username(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "username")))); + linphone_account_creator_set_password(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "password")))); + linphone_account_creator_set_email(creator, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box), "email")))); + linphone_account_creator_enable_newsletter_subscription(creator, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(box), "newsletter")))); + curpage = 5; // Go to page_5_linphone_account_creation_in_progress + break; + case 6: + curpage = 7; // Go to page_7_linphone_account_validation_check_in_progress + break; + default: + break; + } + return curpage; +} + +static GtkWidget * create_intro_page(void) { + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *label = gtk_label_new(_("Welcome!\nThis assistant will help you to use a SIP account for your calls.")); + gtk_box_pack_start(GTK_BOX (vbox), label, TRUE, TRUE, 2); + g_object_set_data(G_OBJECT(vbox), "label", label); gtk_widget_show_all(vbox); return vbox; } -static GtkWidget *create_setup_signin_choice(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *t1=gtk_radio_button_new_with_label(NULL,_("Create an account on linphone.org")); - GtkWidget *t2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a linphone.org account and I just want to use it")); - GtkWidget *t3=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a sip account and I just want to use it")); - GtkWidget *t4=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I want to specify a remote configuration URI")); +static GtkWidget * create_choice_page(void) { + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *t1 = gtk_radio_button_new_with_label(NULL, _("Create an account on linphone.org")); + GtkWidget *t2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1), _("I have already a linphone.org account and I just want to use it")); + GtkWidget *t3 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1), _("I have already a sip account and I just want to use it")); + GtkWidget *t4 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1), _("I want to specify a remote configuration URI")); - gtk_box_pack_start (GTK_BOX (vbox), t1, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t2, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t3, TRUE, TRUE, 2); - gtk_box_pack_start (GTK_BOX (vbox), t4, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX (vbox), t1, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX (vbox), t2, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX (vbox), t3, TRUE, TRUE, 2); + gtk_box_pack_start(GTK_BOX (vbox), t4, TRUE, TRUE, 2); gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"create_account",t1); - g_object_set_data(G_OBJECT(vbox),"setup_linphone_account",t2); - g_object_set_data(G_OBJECT(vbox),"setup_account",t3); - g_object_set_data(G_OBJECT(vbox),"config-uri",t4); + g_object_set_data(G_OBJECT(vbox), "create_account", t1); + g_object_set_data(G_OBJECT(vbox), "setup_linphone_account", t2); + g_object_set_data(G_OBJECT(vbox), "setup_account", t3); + g_object_set_data(G_OBJECT(vbox), "config-uri", t4); return vbox; } -static int all_account_information_entered(GtkWidget *w) { - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - GtkEntry* domain = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"domain")); +static int external_account_configuration_complete(GtkWidget *w) { + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "username")); + GtkEntry* domain = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "domain")); - if (gtk_entry_get_text_length(username) > 0 && - gtk_entry_get_text_length(domain) > 0 && - g_regex_match_simple("^[a-zA-Z0-9]+[a-zA-Z0-9.\\-_]{2,}$", gtk_entry_get_text(username), 0, 0) && - g_regex_match_simple("^(sip:)?([a-zA-Z0-9]+([\\.-][a-zA-Z0-9]+)*)$", gtk_entry_get_text(domain), 0, 0)) { + if ((gtk_entry_get_text_length(username) > 0) + && (gtk_entry_get_text_length(domain) > 0) + && (g_regex_match_simple("^[a-zA-Z0-9]+[a-zA-Z0-9.\\-_]{2,}$", gtk_entry_get_text(username), 0, 0)) + && (g_regex_match_simple("^(sip:)?([a-zA-Z0-9]+([\\.-][a-zA-Z0-9]+)*)$", gtk_entry_get_text(domain), 0, 0))) { return 1; } return 0; } -static void account_informations_changed(GtkEntry *entry, GtkWidget *w) { - GtkWidget *assistant=gtk_widget_get_toplevel(w); - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - all_account_information_entered(w)>0); +static void external_account_configuration_changed(GtkEntry *entry, GtkWidget *w) { + GtkWidget *assistant = gtk_widget_get_toplevel(w); + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), w, external_account_configuration_complete(w) > 0); } -static void linphone_account_informations_changed(GtkEntry *entry, GtkWidget *w) { - GtkWidget *assistant=gtk_widget_get_toplevel(w); - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - gtk_entry_get_text_length(username) > 0); -} - -static GtkWidget *create_linphone_account_informations_page() { - GtkWidget *vbox=gtk_table_new(3, 2, TRUE); - GtkWidget *label=gtk_label_new(_("Enter your linphone.org username")); - - GdkColor color; - GtkWidget *labelEmpty; - GtkWidget *labelUsername; - GtkWidget *entryUsername; - GtkWidget *labelPassword; - GtkWidget *entryPassword; - - gdk_color_parse ("red", &color); - labelEmpty=gtk_label_new(NULL); - gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); - - labelUsername=gtk_label_new(_("Username:")); - entryUsername=gtk_entry_new(); - labelPassword=gtk_label_new(_("Password:")); - entryPassword=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - - gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); - gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); - gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); - - gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)linphone_account_informations_changed,vbox); - return vbox; -} - -static GtkWidget *create_account_informations_page() { - GtkWidget *vbox=gtk_table_new(6, 2, FALSE); - GtkWidget *label=gtk_label_new(_("Enter your account informations")); - +static GtkWidget * create_external_account_configuration_page(void) { + GtkWidget *vbox = gtk_table_new(6, 2, FALSE); + GtkWidget *label = gtk_label_new(_("Enter your account information")); GdkColor color; GtkWidget *labelEmpty; GtkWidget *labelUsername; @@ -131,19 +223,19 @@ static GtkWidget *create_account_informations_page() { GtkWidget *entryUsername; GtkWidget *entryDomain; GtkWidget *entryRoute; - gdk_color_parse ("red", &color); - labelEmpty=gtk_label_new(NULL); - gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); - labelUsername=gtk_label_new(_("Username*")); - labelPassword=gtk_label_new(_("Password*")); - entryPassword=gtk_entry_new(); + gdk_color_parse("red", &color); + labelEmpty = gtk_label_new(NULL); + gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); + labelUsername = gtk_label_new(_("Username*")); + labelPassword = gtk_label_new(_("Password*")); + entryPassword = gtk_entry_new(); gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - labelDomain=gtk_label_new(_("Domain*")); - labelProxy=gtk_label_new(_("Proxy")); - entryUsername=gtk_entry_new(); - entryDomain=gtk_entry_new(); - entryRoute=gtk_entry_new(); + labelDomain = gtk_label_new(_("Domain*")); + labelProxy = gtk_label_new(_("Proxy")); + entryUsername = gtk_entry_new(); + entryDomain = gtk_entry_new(); + entryRoute = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); @@ -157,178 +249,191 @@ static GtkWidget *create_account_informations_page() { gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmpty, 0, 2, 5, 6); gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"domain",entryDomain); - g_object_set_data(G_OBJECT(vbox),"proxy",entryRoute); - g_object_set_data(G_OBJECT(vbox),"errorstring",labelEmpty); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_informations_changed,vbox); - g_signal_connect(G_OBJECT(entryDomain),"changed",(GCallback)account_informations_changed,vbox); - g_signal_connect(G_OBJECT(entryRoute),"changed",(GCallback)account_informations_changed,vbox); + g_object_set_data(G_OBJECT(vbox), "username", entryUsername); + g_object_set_data(G_OBJECT(vbox), "password", entryPassword); + g_object_set_data(G_OBJECT(vbox), "domain", entryDomain); + g_object_set_data(G_OBJECT(vbox), "proxy", entryRoute); + g_object_set_data(G_OBJECT(vbox), "errorstring", labelEmpty); + g_signal_connect(G_OBJECT(entryUsername), "changed", (GCallback)external_account_configuration_changed, vbox); + g_signal_connect(G_OBJECT(entryDomain), "changed", (GCallback)external_account_configuration_changed, vbox); + g_signal_connect(G_OBJECT(entryRoute), "changed", (GCallback)external_account_configuration_changed, vbox); return vbox; } -static int create_account(GtkWidget *page) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - LinphoneProxyConfig *res=linphone_account_creator_validate(creator); - if (res) { - if (!g_regex_match_simple("^sip:[a-zA-Z]+[a-zA-Z0-9.\\-_]{2,}@sip.linphone.org$",creator->username, 0, 0)) { - gchar identity[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", creator->username); - linphone_account_creator_set_username(creator, identity); - linphone_account_creator_set_domain(creator, "sip:sip.linphone.org"); - } +static void linphone_account_configuration_changed(GtkEntry *entry, GtkWidget *w) { + GtkWidget *assistant = gtk_widget_get_toplevel(w); + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "username")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), w, gtk_entry_get_text_length(username) > 0); +} + +static GtkWidget * create_linphone_account_configuration_page(void) { + GtkWidget *vbox = gtk_table_new(3, 2, TRUE); + GtkWidget *label = gtk_label_new(_("Enter your linphone.org username")); + GdkColor color; + GtkWidget *labelEmpty; + GtkWidget *labelUsername; + GtkWidget *entryUsername; + GtkWidget *labelPassword; + GtkWidget *entryPassword; + + gdk_color_parse("red", &color); + labelEmpty = gtk_label_new(NULL); + gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color); + + labelUsername = gtk_label_new(_("Username:")); + entryUsername = gtk_entry_new(); + labelPassword = gtk_label_new(_("Password:")); + entryPassword = gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); + + gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryUsername, 1, 2, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(vbox), labelPassword, 0, 1, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(vbox), entryPassword, 1, 2, 2, 3); + + gtk_widget_show_all(vbox); + g_object_set_data(G_OBJECT(vbox), "username", entryUsername); + g_object_set_data(G_OBJECT(vbox), "password", entryPassword); + g_object_set_data(G_OBJECT(vbox), "errorstring", labelEmpty); + g_signal_connect(G_OBJECT(entryUsername), "changed", (GCallback)linphone_account_configuration_changed, vbox); + return vbox; +} + +static int linphone_account_creation_configuration_correct(GtkWidget *w) { + int is_username_available = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_username_available")); + int is_email_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_email_correct")); + int is_password_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_password_correct")); + if ((is_username_available == 1) && (is_email_correct == 1) && (is_password_correct == 1)) { return 1; } return 0; } -static int is_account_information_correct(GtkWidget *w) { - int is_username_available = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_username_available")); - int is_email_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_email_correct")); - int is_password_correct = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_password_correct")); - - if (is_username_available == 1 && is_email_correct == 1 && is_password_correct == 1) { - return 1; - } - return 0; -} - -static void account_email_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if email entered is correct, and if form is correctly filled, let the user go next page - - GtkEntry* email = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"email")); - GtkImage* isEmailOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"emailOk")); - GtkWidget *assistant=gtk_widget_get_toplevel(w); - - if (g_regex_match_simple("^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$", gtk_entry_get_text(email), 0, 0)) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_email_correct",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isEmailOk, ok); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - g_object_set_data(G_OBJECT(w),"is_email_correct",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isEmailOk, notok); - } - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); -} - -static void account_password_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if passwords entered match, and if form is correctly filled, let the user go next page - - GtkEntry* password = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password")); - GtkImage* isPasswordOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"passwordOk")); - GtkEntry* password_confirm = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"password_confirm")); - GtkWidget *assistant=gtk_widget_get_toplevel(w); - GtkLabel* passwordError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); - - if (gtk_entry_get_text_length(password) >= PASSWORD_MIN_SIZE && - g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_password_correct",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isPasswordOk, ok); - gtk_label_set_text(passwordError, ""); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - if (gtk_entry_get_text_length(password) < PASSWORD_MIN_SIZE) { - gtk_label_set_text(passwordError, "Password is too short !"); - } - else if (!g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { - gtk_label_set_text(passwordError, "Passwords don't match !"); - } - g_object_set_data(G_OBJECT(w),"is_password_correct",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isPasswordOk, notok); - } - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); -} - -gboolean update_interface_with_username_availability(gpointer *w) { +static gboolean update_interface_with_username_availability(void *w) { GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(w)); - GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"usernameOk")); - GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); - int account_existing = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_username_used")); + GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w), "usernameOk")); + GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w), "error")); + int account_existing = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w), "is_username_used")); if (account_existing == 0) { - GdkPixbuf *ok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok")); - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(1)); - gtk_image_set_from_pixbuf(isUsernameOk, ok); + GdkPixbuf *ok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok_pixbuf")); + g_object_set_data(G_OBJECT(w), "is_username_available", GINT_TO_POINTER(1)); + gtk_image_set_from_pixbuf(isUsernameOk, ok_pixbuf); gtk_label_set_text(usernameError, ""); - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); + } else { + GdkPixbuf *nok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "nok_pixbuf")); gtk_label_set_text(usernameError, "Username is already in use !"); - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isUsernameOk, notok); + g_object_set_data(G_OBJECT(w), "is_username_available", GINT_TO_POINTER(0)); + gtk_image_set_from_pixbuf(isUsernameOk, nok_pixbuf); } - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),GTK_WIDGET(w), - is_account_information_correct(GTK_WIDGET(w))>0); - + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), GTK_WIDGET(w), linphone_account_creation_configuration_correct(GTK_WIDGET(w)) > 0); return FALSE; } -void* check_username_availability(void* w) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(GTK_WIDGET(w))); - - int account_existing = linphone_account_creator_test_existence(creator); - - g_object_set_data(G_OBJECT(w),"is_username_used",GINT_TO_POINTER(account_existing)); +static void linphone_gtk_test_account_existence_cb(LinphoneAccountCreator *creator, LinphoneAccountCreatorStatus status, void *user_data) { + GtkWidget *w = (GtkWidget *)user_data; + int account_existing = (status == LinphoneAccountCreatorOk) ? 0 : 1; + g_object_set_data(G_OBJECT(w), "is_username_used", GINT_TO_POINTER(account_existing)); gdk_threads_add_idle((GSourceFunc)update_interface_with_username_availability, (void*)w); - - return NULL; } -static void account_username_changed(GtkEntry *entry, GtkWidget *w) { - // Verifying if username choosed is available, and if form is correctly filled, let the user go next page - GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(w)); - GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w),"username")); - GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w),"usernameOk")); - GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w),"error")); +static gboolean check_username_availability(void *w) { + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(GTK_WIDGET(w))); + g_object_set_data(G_OBJECT(w), "usernameAvailabilityTimerID", GUINT_TO_POINTER(0)); + linphone_account_creator_set_test_existence_cb(creator, linphone_gtk_test_account_existence_cb, w); + linphone_account_creator_test_existence(creator); + return FALSE; +} - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); +static void linphone_account_creation_username_changed(GtkEntry *entry, GtkWidget *w) { + GtkWidget *assistant = gtk_widget_get_toplevel(GTK_WIDGET(w)); + GtkEntry* username = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "username")); + GtkImage* isUsernameOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w), "usernameOk")); + GtkLabel* usernameError = GTK_LABEL(g_object_get_data(G_OBJECT(w), "error")); + + LinphoneAccountCreator *creator = linphone_gtk_assistant_get_creator(assistant); linphone_account_creator_set_username(creator, gtk_entry_get_text(username)); + linphone_account_creator_set_domain(creator, "sip.linphone.org"); + linphone_account_creator_set_route(creator, "sip.linphone.org"); if (g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { -#if !GLIB_CHECK_VERSION(2, 31, 0) - g_thread_create(check_username_availability, (void*)w, FALSE, NULL); -#else - g_thread_new(NULL, check_username_availability, w); -#endif - } - else { - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); + guint timerID = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(w), "usernameAvailabilityTimerID")); + if (timerID > 0) { + g_source_remove(timerID); + } + timerID = g_timeout_add(500, (GSourceFunc)check_username_availability, w); + g_object_set_data(G_OBJECT(w), "usernameAvailabilityTimerID", GUINT_TO_POINTER(timerID)); + } else { + GdkPixbuf *nok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "nok_pixbuf")); if (gtk_entry_get_text_length(username) < LOGIN_MIN_SIZE) { gtk_label_set_text(usernameError, "Username is too short"); - } - else if (!g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { + } else if (!g_regex_match_simple("^[a-zA-Z]+[a-zA-Z0-9.\\-_]{3,}$", gtk_entry_get_text(username), 0, 0)) { gtk_label_set_text(usernameError, "Unauthorized username"); } - g_object_set_data(G_OBJECT(w),"is_username_available",GINT_TO_POINTER(0)); - gtk_image_set_from_pixbuf(isUsernameOk, notok); - - gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant),w, - is_account_information_correct(w)>0); + g_object_set_data(G_OBJECT(w), "is_username_available", GINT_TO_POINTER(0)); + gtk_image_set_from_pixbuf(isUsernameOk, nok_pixbuf); + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), w, linphone_account_creation_configuration_correct(w) > 0); } } -static GtkWidget *create_account_information_page() { - GtkWidget *vbox=gtk_table_new(7, 3, FALSE); - GdkPixbuf *notok = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "notok")); - GtkWidget *label=gtk_label_new(_("(*) Required fields")); - GtkWidget *labelUsername=gtk_label_new(_("Username: (*)")); - GtkWidget *isUsernameOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelPassword=gtk_label_new(_("Password: (*)")); - GtkWidget *isPasswordOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelEmail=gtk_label_new(_("Email: (*)")); - GtkWidget *isEmailOk=gtk_image_new_from_pixbuf(notok); - GtkWidget *labelPassword2=gtk_label_new(_("Confirm your password: (*)")); - GtkWidget *entryUsername=gtk_entry_new(); - GtkWidget *entryPassword=gtk_entry_new(); +static void linphone_account_creation_email_changed(GtkEntry *entry, GtkWidget *w) { + GtkEntry* email = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "email")); + GtkImage* isEmailOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w), "emailOk")); + GtkWidget *assistant = gtk_widget_get_toplevel(w); + + if (g_regex_match_simple("^[a-z0-9]+([_\\.-][a-z0-9]+)*@([a-z0-9]+([\\.-][a-z0-9]+)*)+\\.[a-z]{2,}$", gtk_entry_get_text(email), 0, 0)) { + GdkPixbuf *ok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok_pixbuf")); + g_object_set_data(G_OBJECT(w), "is_email_correct", GINT_TO_POINTER(1)); + gtk_image_set_from_pixbuf(isEmailOk, ok_pixbuf); + } else { + GdkPixbuf *nok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "nok_pixbuf")); + g_object_set_data(G_OBJECT(w), "is_email_correct", GINT_TO_POINTER(0)); + gtk_image_set_from_pixbuf(isEmailOk, nok_pixbuf); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), w, linphone_account_creation_configuration_correct(w) > 0); +} + +static void linphone_account_creation_password_changed(GtkEntry *entry, GtkWidget *w) { + GtkEntry* password = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "password")); + GtkImage* isPasswordOk = GTK_IMAGE(g_object_get_data(G_OBJECT(w), "passwordOk")); + GtkEntry* password_confirm = GTK_ENTRY(g_object_get_data(G_OBJECT(w), "password_confirm")); + GtkWidget *assistant = gtk_widget_get_toplevel(w); + GtkLabel* passwordError = GTK_LABEL(g_object_get_data(G_OBJECT(w), "error")); + + if ((gtk_entry_get_text_length(password) >= PASSWORD_MIN_SIZE) + && (g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0)) { + GdkPixbuf *ok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "ok_pixbuf")); + g_object_set_data(G_OBJECT(w), "is_password_correct", GINT_TO_POINTER(1)); + gtk_image_set_from_pixbuf(isPasswordOk, ok_pixbuf); + gtk_label_set_text(passwordError, ""); + } else { + GdkPixbuf *nok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "nok_pixbuf")); + if (gtk_entry_get_text_length(password) < PASSWORD_MIN_SIZE) { + gtk_label_set_text(passwordError, "Password is too short !"); + } else if (!g_ascii_strcasecmp(gtk_entry_get_text(password), gtk_entry_get_text(password_confirm)) == 0) { + gtk_label_set_text(passwordError, "Passwords don't match !"); + } + g_object_set_data(G_OBJECT(w), "is_password_correct", GINT_TO_POINTER(0)); + gtk_image_set_from_pixbuf(isPasswordOk, nok_pixbuf); + } + gtk_assistant_set_page_complete(GTK_ASSISTANT(assistant), w, linphone_account_creation_configuration_correct(w) > 0); +} + +static GtkWidget * create_linphone_account_creation_configuration_page(void) { + GtkWidget *vbox = gtk_table_new(7, 3, FALSE); + GdkPixbuf *nok_pixbuf = GDK_PIXBUF(g_object_get_data(G_OBJECT(the_assistant), "nok_pixbuf")); + GtkWidget *label = gtk_label_new(_("(*) Required fields")); + GtkWidget *labelUsername = gtk_label_new(_("Username: (*)")); + GtkWidget *isUsernameOk = gtk_image_new_from_pixbuf(nok_pixbuf); + GtkWidget *labelPassword = gtk_label_new(_("Password: (*)")); + GtkWidget *isPasswordOk = gtk_image_new_from_pixbuf(nok_pixbuf); + GtkWidget *labelEmail = gtk_label_new(_("Email: (*)")); + GtkWidget *isEmailOk = gtk_image_new_from_pixbuf(nok_pixbuf); + GtkWidget *labelPassword2 = gtk_label_new(_("Confirm your password: (*)")); + GtkWidget *entryUsername = gtk_entry_new(); + GtkWidget *entryPassword = gtk_entry_new(); GtkWidget *entryEmail; GtkWidget *entryPassword2; GtkWidget *checkNewsletter; @@ -336,22 +441,23 @@ static GtkWidget *create_account_information_page() { GtkWidget *passwordVbox1; GtkWidget *passwordVbox2; GdkColor color; - gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); - entryEmail=gtk_entry_new(); - entryPassword2=gtk_entry_new(); - gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE); - checkNewsletter=gtk_check_button_new_with_label(_("Keep me informed with linphone updates")); - gdk_color_parse ("red", &color); - labelError=gtk_label_new(NULL); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE); + entryEmail = gtk_entry_new(); + entryPassword2 = gtk_entry_new(); + gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE); + checkNewsletter = gtk_check_button_new_with_label(_("Keep me informed with linphone updates")); + + gdk_color_parse("red", &color); + labelError = gtk_label_new(NULL); gtk_widget_modify_fg(labelError, GTK_STATE_NORMAL, &color); - passwordVbox1=gtk_vbox_new(FALSE,2); - passwordVbox2=gtk_vbox_new(FALSE,2); - gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword2, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword, TRUE, FALSE, 2); - gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword2, TRUE, FALSE, 2); + passwordVbox1 = gtk_vbox_new(FALSE, 2); + passwordVbox2 = gtk_vbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX (passwordVbox1), labelPassword, TRUE, FALSE, 2); + gtk_box_pack_start(GTK_BOX (passwordVbox1), labelPassword2, TRUE, FALSE, 2); + gtk_box_pack_start(GTK_BOX (passwordVbox2), entryPassword, TRUE, FALSE, 2); + gtk_box_pack_start(GTK_BOX (passwordVbox2), entryPassword2, TRUE, FALSE, 2); gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 3, 0, 1); gtk_table_attach_defaults(GTK_TABLE(vbox), labelEmail, 0, 1, 1, 2); @@ -367,312 +473,158 @@ static GtkWidget *create_account_information_page() { gtk_table_attach_defaults(GTK_TABLE(vbox), checkNewsletter, 0, 3, 6, 7); gtk_widget_show_all(vbox); - g_object_set_data(G_OBJECT(vbox),"username",entryUsername); - g_object_set_data(G_OBJECT(vbox),"password",entryPassword); - g_object_set_data(G_OBJECT(vbox),"email",entryEmail); - g_object_set_data(G_OBJECT(vbox),"usernameOk",isUsernameOk); - g_object_set_data(G_OBJECT(vbox),"passwordOk",isPasswordOk); - g_object_set_data(G_OBJECT(vbox),"emailOk",isEmailOk); - g_object_set_data(G_OBJECT(vbox),"password_confirm",entryPassword2); - g_object_set_data(G_OBJECT(vbox),"newsletter",checkNewsletter); - g_object_set_data(G_OBJECT(vbox),"error",labelError); - g_signal_connect(G_OBJECT(entryUsername),"changed",(GCallback)account_username_changed,vbox); - g_signal_connect(G_OBJECT(entryPassword),"changed",(GCallback)account_password_changed,vbox); - g_signal_connect(G_OBJECT(entryEmail),"changed",(GCallback)account_email_changed,vbox); - g_signal_connect(G_OBJECT(entryPassword2),"changed",(GCallback)account_password_changed,vbox); + g_object_set_data(G_OBJECT(vbox), "username", entryUsername); + g_object_set_data(G_OBJECT(vbox), "password", entryPassword); + g_object_set_data(G_OBJECT(vbox), "email", entryEmail); + g_object_set_data(G_OBJECT(vbox), "usernameOk", isUsernameOk); + g_object_set_data(G_OBJECT(vbox), "passwordOk", isPasswordOk); + g_object_set_data(G_OBJECT(vbox), "emailOk", isEmailOk); + g_object_set_data(G_OBJECT(vbox), "password_confirm", entryPassword2); + g_object_set_data(G_OBJECT(vbox), "newsletter", checkNewsletter); + g_object_set_data(G_OBJECT(vbox), "error", labelError); + g_signal_connect(G_OBJECT(entryUsername), "changed", (GCallback)linphone_account_creation_username_changed, vbox); + g_signal_connect(G_OBJECT(entryPassword), "changed", (GCallback)linphone_account_creation_password_changed, vbox); + g_signal_connect(G_OBJECT(entryEmail), "changed", (GCallback)linphone_account_creation_email_changed, vbox); + g_signal_connect(G_OBJECT(entryPassword2), "changed", (GCallback)linphone_account_creation_password_changed, vbox); return vbox; } -/* -static GtkWidget *create_confirmation_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(NULL); - gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; -} -*/ - -static GtkWidget *create_error_page(){ - GtkWidget *vbox=gtk_table_new(2, 1, FALSE); - GtkWidget *label=gtk_label_new(_("Error, account not validated, username already used or server unreachable.\nPlease go back and try again.")); - - gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); - - g_object_set_data(G_OBJECT(vbox),"label",label); - gtk_widget_show_all(vbox); - return vbox; -} - -static GtkWidget *create_finish_page(){ - GtkWidget *vbox=gtk_vbox_new(FALSE,2); - GtkWidget *label=gtk_label_new(_("Thank you. Your account is now configured and ready for use.")); +static GtkWidget * create_linphone_account_creation_in_progress_page(void) { + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *label = gtk_label_new(_("Your account is being created, please wait.")); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); gtk_widget_show_all(vbox); return vbox; } -static GtkWidget *wait_for_activation() { - GtkWidget *vbox=gtk_table_new(2, 1, FALSE); - GtkWidget *label=gtk_label_new(_("Please validate your account by clicking on the link we just sent you by email.\n" - "Then come back here and press Next button.")); - +static GtkWidget * create_linphone_account_validation_wait_page(void) { + GtkWidget *vbox = gtk_table_new(2, 1, FALSE); + GtkWidget *label = gtk_label_new(_("Please validate your account by clicking on the link we just sent you by email.\n" + "Then come back here and press Next button.")); gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); - - g_object_set_data(G_OBJECT(vbox),"label",label); + g_object_set_data(G_OBJECT(vbox), "label", label); gtk_widget_show_all(vbox); return vbox; } -static int is_account_validated(GtkWidget *page) { - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(gtk_widget_get_toplevel(page)); - return linphone_account_creator_test_validation(creator); +static GtkWidget * create_linphone_account_validation_check_in_progress_page(void) { + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *label = gtk_label_new(_("Checking if your account is been validated, please wait.")); + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); + gtk_widget_show_all(vbox); + return vbox; } -static void linphone_gtk_assistant_closed(GtkWidget *w){ - linphone_gtk_close_assistant(); +static GtkWidget * create_error_page(void) { + GtkWidget *vbox = gtk_table_new(2, 1, FALSE); + GtkWidget *label = gtk_label_new(_("Error, account not validated, username already used or server unreachable.\nPlease go back and try again.")); + gtk_table_attach(GTK_TABLE(vbox), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND, 0, 100); + g_object_set_data(G_OBJECT(vbox), "label", label); + gtk_widget_show_all(vbox); + return vbox; } -static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page){ - int pagenum=gtk_assistant_get_current_page(GTK_ASSISTANT(assistant)); - - if (pagenum == 5) { - gtk_assistant_commit(GTK_ASSISTANT(assistant)); - } else if (pagenum == gtk_assistant_get_n_pages(GTK_ASSISTANT(assistant)) - 1) { - LinphoneAddress *identity; - LinphoneAuthInfo *info; - // Saving the account and making it default - LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant); - LinphoneProxyConfig *cfg=linphone_proxy_config_new(); - linphone_proxy_config_set_identity(cfg, creator->username); - linphone_proxy_config_set_server_addr(cfg, creator->domain); - linphone_proxy_config_set_route(cfg, creator->route); - linphone_proxy_config_set_expires(cfg, 3600); - linphone_proxy_config_enable_publish(cfg, FALSE); - linphone_proxy_config_enable_register(cfg, TRUE); - - identity = linphone_address_new(creator->username); - info=linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity)); - linphone_core_add_auth_info(linphone_gtk_get_core(),info); - linphone_address_destroy(identity); - - if (strcmp(creator->domain, "sip:sip.linphone.org") == 0) { - linphone_proxy_config_enable_avpf(cfg,TRUE); - // If account created on sip.linphone.org, we configure linphone to use TLS by default - if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) { - LinphoneAddress *addr=linphone_address_new(creator->domain); - char *tmp; - linphone_address_set_transport(addr, LinphoneTransportTls); - tmp=linphone_address_as_string(addr); - linphone_proxy_config_set_server_addr(cfg,tmp); - linphone_proxy_config_set_route(cfg,tmp); - ms_free(tmp); - linphone_address_destroy(addr); - } - linphone_core_set_stun_server(linphone_gtk_get_core(), "stun.linphone.org"); - linphone_core_set_firewall_policy(linphone_gtk_get_core(), LinphonePolicyUseIce); - } - - if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1) - return; - - linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg); - linphone_gtk_load_identities(); - - - } +static GtkWidget * create_finish_page(void) { + GtkWidget *vbox = gtk_vbox_new(FALSE, 2); + GtkWidget *label = gtk_label_new(_("Thank you. Your account is now configured and ready for use.")); + gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 2); + gtk_widget_show_all(vbox); + return vbox; } -static gint destroy_assistant(GtkWidget* w){ - gtk_widget_destroy(w); - the_assistant = NULL; - return FALSE; -} - -static int linphone_gtk_assistant_forward(int curpage, gpointer data){ - GtkWidget *w=(GtkWidget*)data; - GtkWidget *box=gtk_assistant_get_nth_page(GTK_ASSISTANT(w),curpage); - if (curpage==1){ - GtkWidget *create_button=(GtkWidget*)g_object_get_data(G_OBJECT(box),"create_account"); - GtkWidget *setup_linphone_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_linphone_account"); - GtkWidget *setup_account=(GtkWidget*)g_object_get_data(G_OBJECT(box),"setup_account"); - GtkWidget *config_uri=(GtkWidget*)g_object_get_data(G_OBJECT(box),"config-uri"); - - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(create_button))) { - curpage += 3; // Going to P33 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_linphone_account))) { - curpage += 2; // Going to P32 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(setup_account))) { - curpage += 1; // Going to P31 - } - else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(config_uri))) { - /*destroy the assistant and popup config-uri dialog*/ - gtk_widget_hide(w); - linphone_gtk_set_configuration_uri(); - curpage=0; - g_idle_add((GSourceFunc)destroy_assistant,w); - } - } - else if (curpage == 2) { // Account's informations entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - gchar identity[128]; - gchar proxy[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username"))), gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); - - g_snprintf(proxy, sizeof(proxy), "sip:%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain")))); - - linphone_account_creator_set_username(c, identity); - linphone_account_creator_set_domain(c, proxy); - linphone_account_creator_set_route(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"proxy")))); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page - } - else if (curpage == 3) { // Linphone Account's informations entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - gchar identity[128]; - g_snprintf(identity, sizeof(identity), "sip:%s@sip.linphone.org", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); - linphone_account_creator_set_username(c, identity); - linphone_account_creator_set_domain(c, "sip:sip.linphone.org"); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - curpage = gtk_assistant_get_n_pages(GTK_ASSISTANT(w)) - 1; // Going to the last page - } - else if (curpage == 4) { // Password & Email entered - LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w); - linphone_account_creator_set_username(c, gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username")))); - linphone_account_creator_set_password(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"password")))); - linphone_account_creator_set_email(c,gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"email")))); - linphone_account_creator_set_suscribe(c,gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(g_object_get_data(G_OBJECT(box),"newsletter")))); - if (create_account(w) == 1) { - curpage += 1; - } else { // Error when attempting to create the account - curpage += 2; - } - } - else if (curpage == 5) { // Waiting for account validation - if (is_account_validated(w) == 1) { - curpage += 2; // Going to the last page - } else { - curpage += 1; - } - } - else { - curpage += 1; - } - return curpage; -} - -static LinphoneAccountCreator * linphone_gtk_assistant_init(GtkWidget *w){ - const MSList *elem; - LinphoneCore *lc=linphone_gtk_get_core(); - for(elem=linphone_core_get_sip_setups(lc);elem!=NULL;elem=elem->next){ - SipSetup *ss=(SipSetup*)elem->data; - if (sip_setup_get_capabilities(ss) & SIP_SETUP_CAP_ACCOUNT_MANAGER){ - LinphoneAccountCreator *creator=linphone_account_creator_new(lc,ss->name); - g_object_set_data(G_OBJECT(w),"creator",creator); - return creator; - } - } - return NULL; -} - -static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w){ - return (LinphoneAccountCreator*)g_object_get_data(G_OBJECT(w),"creator"); -} - -void linphone_gtk_close_assistant(void){ - if(the_assistant==NULL) - return; - gtk_widget_destroy(the_assistant); - the_assistant = NULL; -} - -void linphone_gtk_show_assistant(GtkWidget *parent){ +void linphone_gtk_show_assistant(GtkWidget *parent) { GtkWidget *w; - GtkWidget *p1; - GtkWidget *p2; - GtkWidget *p31; - GtkWidget *p32; - GtkWidget *p33; - //GtkWidget *confirm; - GtkWidget *validate; - GtkWidget *error; - GtkWidget *end; - GdkPixbuf *ok; - GdkPixbuf *notok; - if(the_assistant!=NULL) - return; - w=the_assistant=gtk_assistant_new(); + GtkWidget *page_0_intro; + GtkWidget *page_1_choice; + GtkWidget *page_2_external_account_configuration; + GtkWidget *page_3_linphone_account_configuration; + GtkWidget *page_4_linphone_account_creation_configuration; + GtkWidget *page_5_linphone_account_creation_in_progress; + GtkWidget *page_6_linphone_account_validation_wait; + GtkWidget *page_7_linphone_account_validation_check_in_progress; + GtkWidget *page_8_error; + GtkWidget *page_9_finish; + GdkPixbuf *ok_pixbuf; + GdkPixbuf *nok_pixbuf; + + if (the_assistant != NULL) return; + + w = the_assistant = gtk_assistant_new(); gtk_window_set_resizable (GTK_WINDOW(w), FALSE); - gtk_window_set_title(GTK_WINDOW(w),_("SIP account configuration assistant")); + gtk_window_set_title(GTK_WINDOW(w), _("SIP account configuration assistant")); - ok = create_pixbuf(linphone_gtk_get_ui_config("ok","ok.png")); - g_object_set_data_full(G_OBJECT(the_assistant), "ok", ok, g_object_unref); - notok = create_pixbuf(linphone_gtk_get_ui_config("notok","notok.png")); - g_object_set_data_full(G_OBJECT(the_assistant), "notok", notok, g_object_unref); + ok_pixbuf = create_pixbuf(linphone_gtk_get_ui_config("ok", "ok.png")); + g_object_set_data_full(G_OBJECT(the_assistant), "ok_pixbuf", ok_pixbuf, g_object_unref); + nok_pixbuf = create_pixbuf(linphone_gtk_get_ui_config("notok", "notok.png")); + g_object_set_data_full(G_OBJECT(the_assistant), "nok_pixbuf", nok_pixbuf, g_object_unref); - p1=create_intro(); - p2=create_setup_signin_choice(); - p31=create_account_informations_page(); - p32=create_linphone_account_informations_page(); - p33=create_account_information_page(); - //confirm=create_confirmation_page(); - validate=wait_for_activation(); - error=create_error_page(); - end=create_finish_page(); + page_0_intro = create_intro_page(); + page_1_choice = create_choice_page(); + page_2_external_account_configuration = create_external_account_configuration_page(); + page_3_linphone_account_configuration = create_linphone_account_configuration_page(); + page_4_linphone_account_creation_configuration = create_linphone_account_creation_configuration_page(); + page_5_linphone_account_creation_in_progress = create_linphone_account_creation_in_progress_page(); + page_6_linphone_account_validation_wait = create_linphone_account_validation_wait_page(); + page_7_linphone_account_validation_check_in_progress = create_linphone_account_validation_check_in_progress_page(); + page_8_error = create_error_page(); + page_9_finish = create_finish_page(); linphone_gtk_assistant_init(w); - gtk_assistant_append_page(GTK_ASSISTANT(w),p1); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p1,GTK_ASSISTANT_PAGE_INTRO); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p1,_("Welcome to the account setup assistant")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p1,TRUE); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_0_intro); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_0_intro, GTK_ASSISTANT_PAGE_INTRO); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_0_intro, _("Welcome to the account setup assistant")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w), page_0_intro, TRUE); - gtk_assistant_append_page(GTK_ASSISTANT(w),p2); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p2,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p2,_("Account setup assistant")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p2,TRUE); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_1_choice); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_1_choice, GTK_ASSISTANT_PAGE_CONTENT); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_1_choice, _("Account setup assistant")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w), page_1_choice, TRUE); - gtk_assistant_append_page(GTK_ASSISTANT(w),p31); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p31,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p31,FALSE); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p31,_("Configure your account (step 1/1)")); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_2_external_account_configuration); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_2_external_account_configuration, GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_2_external_account_configuration, _("Configure your account (step 1/1)")); - gtk_assistant_append_page(GTK_ASSISTANT(w),p32); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p32,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),p32,FALSE); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p32,_("Enter your sip username (step 1/1)")); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_3_linphone_account_configuration); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_3_linphone_account_configuration, GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_3_linphone_account_configuration, _("Enter your sip username (step 1/1)")); - gtk_assistant_append_page(GTK_ASSISTANT(w),p33); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),p33,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),p33,_("Enter account information (step 1/2)")); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_4_linphone_account_creation_configuration); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_4_linphone_account_creation_configuration, GTK_ASSISTANT_PAGE_CONFIRM); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_4_linphone_account_creation_configuration, _("Enter account information (step 1/2)")); - /*gtk_assistant_append_page(GTK_ASSISTANT(w),confirm); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),confirm,GTK_ASSISTANT_PAGE_CONFIRM); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),confirm,_("Confirmation (step 2/2)")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),confirm,TRUE);*/ + gtk_assistant_append_page(GTK_ASSISTANT(w), page_5_linphone_account_creation_in_progress); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_5_linphone_account_creation_in_progress, GTK_ASSISTANT_PAGE_PROGRESS); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_5_linphone_account_creation_in_progress, _("Account creation in progress")); - gtk_assistant_append_page(GTK_ASSISTANT(w),validate); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),validate,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),validate,_("Validation (step 2/2)")); - gtk_assistant_set_page_complete(GTK_ASSISTANT(w),validate,TRUE); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_6_linphone_account_validation_wait); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_6_linphone_account_validation_wait, GTK_ASSISTANT_PAGE_CONTENT); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_6_linphone_account_validation_wait, _("Validation (step 2/2)")); + gtk_assistant_set_page_complete(GTK_ASSISTANT(w), page_6_linphone_account_validation_wait, TRUE); - gtk_assistant_append_page(GTK_ASSISTANT(w),error); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),error,GTK_ASSISTANT_PAGE_CONTENT); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),error,_("Error")); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_7_linphone_account_validation_check_in_progress); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_7_linphone_account_validation_check_in_progress, GTK_ASSISTANT_PAGE_PROGRESS); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_7_linphone_account_validation_check_in_progress, _("Account validation check in progress")); - gtk_assistant_append_page(GTK_ASSISTANT(w),end); - gtk_assistant_set_page_type(GTK_ASSISTANT(w),end,GTK_ASSISTANT_PAGE_SUMMARY); - gtk_assistant_set_page_title(GTK_ASSISTANT(w),end,_("Terminating")); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_8_error); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_8_error, GTK_ASSISTANT_PAGE_CONTENT); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_8_error, _("Error")); - gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w),linphone_gtk_assistant_forward,w,NULL); - g_signal_connect(G_OBJECT(w),"close",(GCallback)linphone_gtk_assistant_closed,NULL); - g_signal_connect(G_OBJECT(w),"cancel",(GCallback)linphone_gtk_assistant_closed,NULL); - g_signal_connect(G_OBJECT(w),"prepare",(GCallback)linphone_gtk_assistant_prepare,NULL); + gtk_assistant_append_page(GTK_ASSISTANT(w), page_9_finish); + gtk_assistant_set_page_type(GTK_ASSISTANT(w), page_9_finish, GTK_ASSISTANT_PAGE_SUMMARY); + gtk_assistant_set_page_title(GTK_ASSISTANT(w), page_9_finish, _("Terminating")); + + gtk_assistant_set_forward_page_func(GTK_ASSISTANT(w), linphone_gtk_assistant_forward, w, NULL); + g_signal_connect(G_OBJECT(w), "close", (GCallback)linphone_gtk_assistant_closed, NULL); + g_signal_connect(G_OBJECT(w), "cancel", (GCallback)linphone_gtk_assistant_closed, NULL); + g_signal_connect(G_OBJECT(w), "prepare", (GCallback)linphone_gtk_assistant_prepare, NULL); - gtk_window_set_transient_for(GTK_WINDOW(the_assistant), GTK_WINDOW(parent)); + gtk_window_set_transient_for(GTK_WINDOW(the_assistant), GTK_WINDOW(linphone_gtk_get_main_window())); gtk_widget_show(w); } +void linphone_gtk_close_assistant(void) { + if (the_assistant == NULL) return; + gtk_widget_destroy(the_assistant); + the_assistant = NULL; +}