diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index b95ee4e74..1b62c3a11 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1265,7 +1265,7 @@ 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) { +void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message) { if (lc->vtable.configuring_status) lc->vtable.configuring_status(lc, state, message); @@ -1274,6 +1274,7 @@ static void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfigurin static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtable, LpConfig *config, void * userdata) { + const char *remote_provisioning_uri = NULL; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); memset (lc, 0, sizeof (LinphoneCore)); lc->config=config; @@ -1358,15 +1359,21 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab lc->network_last_check = 0; lc->network_last_status = FALSE; + + lc->http_provider = belle_sip_stack_create_http_provider(sal_get_belle_sip_stack(lc->sal), "0.0.0.0"); + + certificates_config_read(lc); + belle_tls_verify_policy_t *tls_policy = belle_tls_verify_policy_new(); + belle_tls_verify_policy_set_root_ca(tls_policy, sal_get_root_ca(lc->sal)); + belle_http_provider_set_tls_verify_policy(lc->http_provider, tls_policy); if (lc->vtable.display_status) lc->vtable.display_status(lc, _("Configuring")); linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring"); - const char *remote_provisioning_uri = lp_config_get_string(lc->config, "app", "remote_provisioning", NULL); + remote_provisioning_uri = lp_config_get_string(lc->config, "app", "remote_provisioning", NULL); if (remote_provisioning_uri) { - certificates_config_read(lc); - linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri, linphone_configuring_terminated); + linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri); } else { linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL); } @@ -5470,6 +5477,9 @@ void net_config_uninit(LinphoneCore *lc) { net_config_t *config=&lc->net_conf; + if (lc->http_provider) { + belle_sip_object_unref(lc->http_provider); + } if (config->stun_server!=NULL){ ms_free(config->stun_server); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index fd042589e..8fefaf7f6 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -2303,16 +2303,6 @@ LINPHONE_PUBLIC void linphone_core_set_provisioning_uri(LinphoneCore *lc, const **/ LINPHONE_PUBLIC const char* linphone_core_get_provisioning_uri(const LinphoneCore *lc); -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 void linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri, ConfiguringCallback cb); - #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index af5459035..ca9054d8f 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -673,6 +673,7 @@ struct _LinphoneCore #ifdef BUILD_UPNP UpnpContext *upnp; #endif //BUILD_UPNP + belle_http_provider_t *http_provider; }; @@ -806,6 +807,14 @@ const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, cons void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc); +/***************************************************************************** + * REMOTE PROVISIONING FUNCTIONS * + ****************************************************************************/ + +void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message); +void linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri); + + /***************************************************************************** * XML UTILITY FUNCTIONS * ****************************************************************************/ diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c index 127dce956..99b4c1292 100644 --- a/coreapi/remote_provisioning.c +++ b/coreapi/remote_provisioning.c @@ -21,9 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #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); @@ -44,22 +41,18 @@ static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml if (result == 0) { lp_config_sync(linphone_core_get_config(lc)); xml2lpc_context_destroy(context); - if (linphone_callback) - linphone_callback(lc, LinphoneConfiguringSuccessful, NULL); + linphone_configuring_terminated(lc, LinphoneConfiguringSuccessful, NULL); } else { xml2lpc_context_destroy(context); - if (linphone_callback) - linphone_callback(lc, LinphoneConfiguringFailed, "convert failed"); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "xml to lpc failed"); } } else { xml2lpc_context_destroy(context); - if (linphone_callback) - linphone_callback(lc, LinphoneConfiguringFailed, "set xml string failed"); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "invalid xml"); } } 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); @@ -67,75 +60,41 @@ static void belle_request_process_response_event(void *ctx, const belle_http_res 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); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "http error"); } } 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"); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "http 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"); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "http 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"); + linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "http 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 -}; +void linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri) { + 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); + belle_http_provider_send_request(lc->http_provider, request, listener); } void linphone_core_set_provisioning_uri(LinphoneCore *lc, const char*uri){ diff --git a/coreapi/sal.c b/coreapi/sal.c index babb2af4d..de5f235df 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -26,6 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "config.h" #endif #include "sal/sal.h" +#include "bellesip_sal/sal_impl.h" #include @@ -626,5 +627,7 @@ int sal_body_has_type(const SalBody *body, const char *type, const char *subtype && strcmp(body->subtype,subtype)==0; } - +belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal) { + return sal->stack; +} diff --git a/include/sal/sal.h b/include/sal/sal.h index a216730b1..db2625329 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -697,4 +697,6 @@ int sal_body_has_type(const SalBody *body, const char *type, const char *subtype /*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/ int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size); +belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal); + #endif diff --git a/tester/Makefile.am b/tester/Makefile.am index f1d5f1f8e..22949b61f 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -1,4 +1,5 @@ EXTRA_DIST= empty_rc laure_rc marie_early_rc marie_no_sdp_rc marie_rc multi_account_lrc pauline_alt_rc \ + marie_remote_rc pauline_remote_rc marie_remote_404_rc marie_remote_invalid_rc \ pauline_rc pauline_wild_rc pauline_rc_tcp tester_hosts sounds images certificates @@ -15,7 +16,8 @@ liblinphone_tester_SOURCES= liblinphone_tester.c liblinphone_tester.h\ upnp_tester.c \ eventapi_tester.c \ flexisip_tester.c \ - stun_tester.c + stun_tester.c \ + remote_provisioning_tester.c #liblinphone_tester_CFLAGS=$(CUNIT_CFLAGS) diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 9f654542c..7a7346f51 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -25,7 +25,7 @@ #include "CUnit/CUCurses.h" #endif -static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file); +static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data); static test_suite_t **test_suite = NULL; static int nb_test_suites = 0; @@ -90,7 +90,7 @@ void reset_counters( stats* counters) { memset(counters,0,sizeof(stats)); } -static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file) { +static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* path, const char* file, void* user_data) { LinphoneCore* lc; char filepath[256]={0}; char ringpath[256]={0}; @@ -106,7 +106,7 @@ static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char* CU_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0); } - lc = linphone_core_new(v_table,NULL,*filepath!='\0' ? filepath : NULL,NULL); + lc = linphone_core_new(v_table,NULL,*filepath!='\0' ? filepath : NULL, user_data); sal_enable_test_features(lc->sal,TRUE); snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cn/cafile.pem", path); @@ -200,9 +200,10 @@ LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_f mgr->v_table.subscription_state_changed=linphone_subscription_state_change; mgr->v_table.notify_received=linphone_notify_received; mgr->v_table.publish_state_changed=linphone_publish_state_changed; - mgr->lc=configure_lc_from(&mgr->v_table, liblinphone_tester_file_prefix, rc_file); - linphone_core_set_user_data(mgr->lc,mgr); + mgr->v_table.configuring_status=linphone_configuration_status; + reset_counters(&mgr->stat); + mgr->lc=configure_lc_from(&mgr->v_table, liblinphone_tester_file_prefix, rc_file, mgr); /*CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count);*/ if (check_for_proxies && rc_file) /**/ proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)); @@ -328,6 +329,7 @@ void liblinphone_tester_init(void) { add_test_suite(&stun_test_suite); add_test_suite(&event_test_suite); add_test_suite(&flexisip_test_suite); + add_test_suite(&remote_provisioning_test_suite); } void liblinphone_tester_uninit(void) { diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index b2987a408..edf51e1fb 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -55,6 +55,7 @@ extern test_suite_t upnp_test_suite; extern test_suite_t event_test_suite; extern test_suite_t flexisip_test_suite; extern test_suite_t stun_test_suite; +extern test_suite_t remote_provisioning_test_suite; extern int liblinphone_tester_nb_test_suites(void); @@ -173,6 +174,10 @@ typedef struct _stats { int number_of_LinphonePublishExpiring; int number_of_LinphonePublishError; int number_of_LinphonePublishCleared; + + int number_of_LinphoneConfiguringSkipped; + int number_of_LinphoneConfiguringFailed; + int number_of_LinphoneConfiguringSuccessful; }stats; typedef struct _LinphoneCoreManager { @@ -203,6 +208,7 @@ void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *ev, LinphoneSubscriptionState state); void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state); void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content); +void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message); LinphoneAddress * create_linphone_address(const char * domain); bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value); diff --git a/tester/marie_remote_404_rc b/tester/marie_remote_404_rc new file mode 100644 index 000000000..1ca04f8de --- /dev/null +++ b/tester/marie_remote_404_rc @@ -0,0 +1,2 @@ +[app] +remote_provisioning=http://smtp.linphone.org/marie_404 diff --git a/tester/marie_remote_invalid_rc b/tester/marie_remote_invalid_rc new file mode 100644 index 000000000..1e52d7f37 --- /dev/null +++ b/tester/marie_remote_invalid_rc @@ -0,0 +1,2 @@ +[app] +remote_provisioning=http://smtp.linphone.org/marie_invalid diff --git a/tester/marie_remote_rc b/tester/marie_remote_rc new file mode 100644 index 000000000..faeb2cdd0 --- /dev/null +++ b/tester/marie_remote_rc @@ -0,0 +1,2 @@ +[app] +remote_provisioning=http://smtp.linphone.org/marie_xml diff --git a/tester/marie_xml b/tester/marie_xml new file mode 100644 index 000000000..5818930ba --- /dev/null +++ b/tester/marie_xml @@ -0,0 +1,50 @@ + + +
+ -1 + -1 + -1 + 0 + 0 + 0 + 1 +
+
+ marie + marie + secret + sip.example.org +
+
+ sip.example.org;transport=tcp + sip.example.org;transport=tcp;lr + sip:marie@sip.example.org + 3600 + 1 + 0 + 0 +
+
+ "Paupoche" <sip:pauline@sip.example.org> + accept + 0 +
+
+ 8070 + 9072 +
+
+ 0 + 0 + 0 + vga + 0 + 0 + 0 + 0 + StaticImage: Static picture +
+
+ 0 #to not overload cpu in case of VG +
+
diff --git a/tester/pauline_remote_rc b/tester/pauline_remote_rc new file mode 100644 index 000000000..276bb1f54 --- /dev/null +++ b/tester/pauline_remote_rc @@ -0,0 +1,2 @@ +[app] +remote_provisioning=https://smtp.linphone.org/pauline_xml diff --git a/tester/pauline_xml b/tester/pauline_xml new file mode 100644 index 000000000..cc952af82 --- /dev/null +++ b/tester/pauline_xml @@ -0,0 +1,45 @@ + + +
+ -1 + -1 + -1 + 0 + 0 + 0 + 1 +
+
+ pauline + pauline + secret + sip.example.org +
+
+ sip2.linphone.org;transport=tls + sip2.linphone.org;transport=tls + sip:pauline@sip.example.org + 3600 + 1 + 0 + 0 +
+
+ 8090 + 9092 +
+
+ 0 + 0 + 0 + vga + 0 + 0 + 0 + 0 + StaticImage: Static picture +
+
+ 0 #to not overload cpu in case of VG +
+
diff --git a/tester/remote_provisioning_tester.c b/tester/remote_provisioning_tester.c new file mode 100644 index 000000000..7d73418bf --- /dev/null +++ b/tester/remote_provisioning_tester.c @@ -0,0 +1,80 @@ +/* + liblinphone_tester - liblinphone test suite + Copyright (C) 2013 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, see . +*/ + +#include +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" + +void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { + stats* counters = get_stats(lc); + if (status == LinphoneConfiguringSkipped) { + counters->number_of_LinphoneConfiguringSkipped++; + } else if (status == LinphoneConfiguringFailed) { + counters->number_of_LinphoneConfiguringFailed++; + } else if (status == LinphoneConfiguringSuccessful) { + counters->number_of_LinphoneConfiguringSuccessful++; + } +} + +static void remote_provisioning_skipped(void) { + LinphoneCoreManager* marie = linphone_core_manager_new2("marie_rc", FALSE); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSkipped,1)); + linphone_core_manager_destroy(marie); +} + +static void remote_provisioning_http(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_remote_rc"); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringSuccessful,1)); + linphone_core_manager_destroy(marie); +} + +static void remote_provisioning_https(void) { + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_remote_rc"); + CU_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneConfiguringSuccessful,1)); + linphone_core_manager_destroy(pauline); +} + +static void remote_provisioning_not_found(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_remote_404_rc"); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringFailed,1)); + linphone_core_manager_destroy(marie); +} + +static void remote_provisioning_invalid(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_remote_invalid_rc"); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphoneConfiguringFailed,1)); + linphone_core_manager_destroy(marie); +} + +test_t remote_provisioning_tests[] = { + { "Remote provisioning skipped", remote_provisioning_skipped }, + { "Remote provisioning successful behind http", remote_provisioning_http }, + { "Remote provisioning successful behind https", remote_provisioning_https }, + { "Remote provisioning 404 not found", remote_provisioning_not_found }, + { "Remote provisioning invalid", remote_provisioning_invalid } +}; + +test_suite_t remote_provisioning_test_suite = { + "RemoteProvisioning", + NULL, + NULL, + sizeof(remote_provisioning_tests) / sizeof(remote_provisioning_tests[0]), + remote_provisioning_tests +}; \ No newline at end of file