diff --git a/build/android/Android.mk b/build/android/Android.mk index f4601822a60d45bbc006e28dfb8283c233a651fc..bd59cb4e3bd097083fc75194dc3f83447947fb02 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -209,8 +209,8 @@ ifeq ($(BUILD_REMOTE_PROVISIONING),1) LOCAL_SRC_FILES += ../coreapi/xml2lpc.c \ ../tools/xml2lpc_jni.cc \ ../coreapi/lpc2xml.c \ - ../tools/lpc2xml_jni.cc - + ../tools/lpc2xml_jni.cc \ + ../coreapi/remote_provisioning.c endif ifeq ($(BUILD_SQLITE),1) diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index e8b640c32228f2b5d606eb4300df06d61cba6cb0..68d78447f28dec30bf706ea4ad9f2820e30e5221 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -55,6 +55,7 @@ liblinphone_la_SOURCES=\ xml.c \ xml2lpc.c \ lpc2xml.c \ + remote_provisioning.c \ $(GITVERSION_FILE) if BUILD_UPNP diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index de3db32fd98f6a161e17b0b101891150467407dc..5a9b834e6a7798aa029b558335189ece5bd29456 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1265,6 +1265,13 @@ static void linphone_core_start(LinphoneCore * lc) { linphone_core_set_state(lc,LinphoneGlobalOn,"Ready"); } +static void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message) { + if (lc->vtable.configuring_status) + lc->vtable.configuring_status(lc, state, message); + + linphone_core_start(lc); +} + static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata) { ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -1357,15 +1364,12 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring"); const char *remote_provisioning_uri = lp_config_get_string(lc->config, "app", "remote_provisioning", NULL); - LinphoneConfiguringState configuring_result = LinphoneConfiguringSkipped; if (remote_provisioning_uri) { certificates_config_read(lc); + linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri, linphone_configuring_terminated); + } else { + linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL); } - - if (lc->vtable.configuring_status) - lc->vtable.configuring_status(lc, configuring_result, configuring_result == LinphoneConfiguringFailed ? _("Configuring failed") : NULL); - - linphone_core_start(lc); } /** diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index c7d05d01779c704cb673c0dde9d189a3b83a1c3f..e91d627ac9f1c3aa51b0d0cfb5d22699370883d2 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2281,13 +2281,15 @@ typedef void (*ContactSearchCallback)( LinphoneContactSearch* id, MSList* friend /** Remote provisioning */ +typedef void (*ConfiguringCallback)(LinphoneCore *lc, LinphoneConfiguringState state, const char *message); + /** * Download a remote provisioning file from the given uri and applies it to current lp config. * A restart is requiered for the changes to be applied. * @param lc the LinphoneCore * @param remote_provisioning_uri the URI at which the remote provisioning file is available */ -LINPHONE_PUBLIC LinphoneConfiguringState linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri); +LINPHONE_PUBLIC void linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri, ConfiguringCallback cb); #ifdef __cplusplus } diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c new file mode 100644 index 0000000000000000000000000000000000000000..fe4269a668d3e3796ae37db36f6f0cc2142e30ec --- /dev/null +++ b/coreapi/remote_provisioning.c @@ -0,0 +1,140 @@ +/* +remote_provisioning.c +Copyright (C) 2010 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 "bellesip_sal/sal_impl.h" +#include "xml2lpc.h" + +#define XML2LPC_CALLBACK_BUFFER_SIZE 1024 + +static ConfiguringCallback linphone_callback = NULL; +static bool_t waiting_response = FALSE; + +static void xml2lpc_callback(void *ctx, xml2lpc_log_level level, const char *fmt, va_list list) { + char buffer[XML2LPC_CALLBACK_BUFFER_SIZE]; + vsnprintf(buffer, XML2LPC_CALLBACK_BUFFER_SIZE, fmt, list); + + if (level == XML2LPC_ERROR) + ms_error("%s", buffer); + else if (level == XML2LPC_WARNING) + ms_warning("%s", buffer); + /*else + ms_message("%s", buffer); // Don't log debug messages */ +} + +static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml) { + xml2lpc_context *context = xml2lpc_context_new(xml2lpc_callback, lc); + int result = xml2lpc_set_xml_string(context, xml); + if (result == 0) { + result = xml2lpc_convert(context, linphone_core_get_config(lc)); + if (result == 0) { + lp_config_sync(linphone_core_get_config(lc)); + xml2lpc_context_destroy(context); + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringSuccessful, NULL); + } else { + xml2lpc_context_destroy(context); + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, "convert failed"); + } + } else { + xml2lpc_context_destroy(context); + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, "set xml string failed"); + } +} + +static void belle_request_process_response_event(void *ctx, const belle_http_response_event_t *event) { + waiting_response = FALSE; + LinphoneCore *lc = (LinphoneCore *)ctx; + belle_sip_message_t *body = BELLE_SIP_MESSAGE(event->response); + const char *message = belle_sip_message_get_body(body); + + if (belle_http_response_get_status_code(event->response) == 200) { + linphone_remote_provisioning_apply(lc, message); + } else { + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, message); + } +} + +static void belle_request_process_io_error(void *ctx, const belle_sip_io_error_event_t *event) { + waiting_response = FALSE; + LinphoneCore *lc = (LinphoneCore *)ctx; + + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, "io error"); +} + +static void belle_request_process_timeout(void *ctx, const belle_sip_timeout_event_t *event) { + waiting_response = FALSE; + LinphoneCore *lc = (LinphoneCore *)ctx; + + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, "timeout"); +} + +static void belle_request_process_auth_requested(void *ctx, belle_sip_auth_event_t *event) { + waiting_response = FALSE; + LinphoneCore *lc = (LinphoneCore *)ctx; + + if (linphone_callback) + linphone_callback(lc, LinphoneConfiguringFailed, "auth requested"); +} + +static belle_http_request_listener_callbacks_t belle_request_listener = { + belle_request_process_response_event, + belle_request_process_io_error, + belle_request_process_timeout, + belle_request_process_auth_requested +}; + +static void linphone_remote_provisioning_download(LinphoneCore *lc, const char *remote_provisioning_uri) { + belle_sip_object_pool_t *pool = belle_sip_object_pool_push(); + belle_sip_stack_t *stack = belle_sip_stack_new(NULL); + + belle_http_request_listener_t *listener = belle_http_request_listener_create_from_callbacks(&belle_request_listener, lc); + belle_http_provider_t *provider = belle_sip_stack_create_http_provider(stack, "0.0.0.0"); + + belle_http_request_t *request = belle_http_request_create( + "GET", + belle_generic_uri_parse(remote_provisioning_uri), + NULL + ); + + belle_http_provider_send_request(provider, request, listener); + + waiting_response = TRUE; + while (waiting_response) { + belle_sip_stack_sleep(stack, 10); + } + + belle_sip_object_unref(pool); + belle_sip_object_unref(provider); + belle_sip_object_unref(stack); +} + +/** + * Fetches the remote provisioning from the given URI and tries to apply it to the current LpConfig + * @param lc the LinphoneCore + * @param remote_provisioning_uri the URI at which the provisioning is available + */ +void linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri, ConfiguringCallback cb) { + linphone_callback = cb; + linphone_remote_provisioning_download(lc, remote_provisioning_uri); +} \ No newline at end of file diff --git a/gtk/main.c b/gtk/main.c index bb000296c620229189210565743b60fa524a6ba2..761342ee66ac08adf361187bcd53b4464dd8c522 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1240,9 +1240,7 @@ static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){ } static void linphone_gtk_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { - if (status == LinphoneConfiguringFailed) { - linphone_gtk_display_something(GTK_MESSAGE_ERROR, message); - } + } static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg){