Commit dee261a4 authored by François Grisez's avatar François Grisez

Prevent linphone_core_start() aborting when connecting to database failed

A return value has been added to linphone_core_start() to notify the caller
whether a synchronous error has occured while starting.
parent 88563aba
......@@ -2496,50 +2496,57 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig
}
}
void linphone_core_start (LinphoneCore *lc) {
if (lc->state == LinphoneGlobalOn) {
bctbx_warning("Core is already started, skipping...");
return;
} else if (lc->state == LinphoneGlobalShutdown) {
bctbx_error("Can't start a Core that is stopping, wait for Off state");
return;
} else if (lc->state == LinphoneGlobalOff) {
bctbx_warning("Core was stopped, before starting it again we need to init it");
linphone_core_init(lc, NULL, lc->config, lc->data, NULL, FALSE);
LinphoneStatus linphone_core_start (LinphoneCore *lc) {
try {
if (lc->state == LinphoneGlobalOn) {
bctbx_warning("Core is already started, skipping...");
return -1;
} else if (lc->state == LinphoneGlobalShutdown) {
bctbx_error("Can't start a Core that is stopping, wait for Off state");
return -1;
} else if (lc->state == LinphoneGlobalOff) {
bctbx_warning("Core was stopped, before starting it again we need to init it");
linphone_core_init(lc, NULL, lc->config, lc->data, NULL, FALSE);
// Decrement refs to avoid leaking
lp_config_unref(lc->config);
linphone_core_deactivate_log_serialization_if_needed();
bctbx_uninit_logger();
}
// Decrement refs to avoid leaking
lp_config_unref(lc->config);
linphone_core_deactivate_log_serialization_if_needed();
bctbx_uninit_logger();
}
linphone_core_set_state(lc, LinphoneGlobalStartup, "Starting up");
linphone_core_set_state(lc, LinphoneGlobalStartup, "Starting up");
L_GET_PRIVATE_FROM_C_OBJECT(lc)->init();
L_GET_PRIVATE_FROM_C_OBJECT(lc)->init();
//to give a chance to change uuid before starting
const char* uuid=lp_config_get_string(lc->config,"misc","uuid",NULL);
if (!uuid){
string uuid = lc->sal->createUuid();
lp_config_set_string(lc->config,"misc","uuid",uuid.c_str());
}else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/
lc->sal->setUuid(uuid);
//to give a chance to change uuid before starting
const char* uuid=lp_config_get_string(lc->config,"misc","uuid",NULL);
if (!uuid){
string uuid = lc->sal->createUuid();
lp_config_set_string(lc->config,"misc","uuid",uuid.c_str());
}else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/
lc->sal->setUuid(uuid);
if (!lc->sal->getRootCa().empty()) {
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa().c_str());
belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config);
}
if (!lc->sal->getRootCa().empty()) {
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa().c_str());
belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config);
}
getPlatformHelpers(lc)->onLinphoneCoreStart(!!lc->auto_net_state_mon);
getPlatformHelpers(lc)->onLinphoneCoreStart(!!lc->auto_net_state_mon);
linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring");
linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring");
const char *remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
if (remote_provisioning_uri) {
if (linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri) == -1)
linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "Bad URI");
} else {
linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL);
}
const char *remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
if (remote_provisioning_uri) {
if (linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri) == -1)
linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "Bad URI");
} else {
linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL);
return 0;
} catch (const CorePrivate::DatabaseConnectionFailure &e) {
bctbx_error("%s", e.what());
return -2;
}
}
......
......@@ -1039,8 +1039,9 @@ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneCore *linphone_core_new_with_config(
* Must be called only if #LinphoneGlobalState is either Ready of Off. State will changed to Startup, Configuring and then On.
* @ingroup initializing
* @param[in] core The #LinphoneCore object to be started
* @return 0: success, -1: global failure, -2: could not connect database
*/
LINPHONE_PUBLIC void linphone_core_start (LinphoneCore *core);
LINPHONE_PUBLIC LinphoneStatus linphone_core_start(LinphoneCore *lc);
/**
* Stop a #LinphoneCore object after it has been instantiated and started.
......
......@@ -20,6 +20,8 @@
#ifndef _L_CORE_P_H_
#define _L_CORE_P_H_
#include <stdexcept>
#include "chat/chat-room/abstract-chat-room.h"
#include "core.h"
#include "db/main-db.h"
......@@ -37,6 +39,12 @@ class RemoteConferenceListEventHandler;
class CorePrivate : public ObjectPrivate {
public:
class DatabaseConnectionFailure : public std::runtime_error {
public:
DatabaseConnectionFailure(const char *what) : std::runtime_error(what) {}
DatabaseConnectionFailure(const std::string &what) : std::runtime_error(what) {}
};
void init ();
void registerListener (CoreListener *listener);
void unregisterListener (CoreListener *listener);
......
......@@ -70,8 +70,11 @@ void CorePrivate::init () {
if (uri != "null"){ //special uri "null" means don't open database. We need this for tests.
lInfo() << "Opening linphone database " << uri << " with backend " << backend;
if (!mainDb->connect(backend, uri))
lFatal() << "Unable to open linphone database with uri " << uri << " and backend " << backend;
if (!mainDb->connect(backend, uri)) {
ostringstream os;
os << "Unable to open linphone database with uri " << uri << " and backend " << backend;
throw DatabaseConnectionFailure(os.str());
}
loadChatRooms();
} else lWarning() << "Database explicitely not requested, this Core is built with no database support.";
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment