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

Release the reference on the focus call when thatone fails

parent ca8d64d5
This diff is collapsed.
......@@ -37,11 +37,18 @@ extern "C" {
* @{
*/
/**
* LinphoneConference class
*/
typedef struct _LinphoneConference LinphoneConference;
/**
* Parameters for initialization of conferences
*/
typedef struct _LinphoneCorferenceParams LinphoneConferenceParams;
/**
* Create a #LinphoneConferenceParams with default parameters set.
* @param core #LinphoneCore to use to find out the default parameters. Can be NULL.
......@@ -73,10 +80,7 @@ LINPHONE_PUBLIC bool_t linphone_conference_params_video_requested(const Linphone
/**
* LinphoneConference class
*/
typedef struct _LinphoneConference LinphoneConference;
/**
* Remove a participant from a conference
......
......@@ -37,11 +37,48 @@ typedef enum {
LinphoneConferenceClassRemote
} LinphoneConferenceClass;
/**
* List of states used by #LinphoneConference
*/
typedef enum {
LinphoneConferenceStopped, /*< Initial state */
LinphoneConferenceStarting, /*< A participant has been added but the conference is not running yet */
LinphoneConferenceReady, /*< The conference is running */
LinphoneConferenceStartingFailed /*< A participant has been added but the initialization of the conference has failed */
} LinphoneConferenceState;
/**
* Type of the funtion to pass as callback to linphone_conference_params_set_state_changed_callback()
* @param conference The conference instance which the state has changed
* @param new_state The new state of the conferenece
* @param user_data Pointer pass to user_data while linphone_conference_params_set_state_changed_callback() was being called
*/
typedef void (*LinphoneConferenceStateChangedCb)(LinphoneConference *conference, LinphoneConferenceState new_state, void *user_data);
/**
* A function to converte a #LinphoneConferenceState into a string
*/
const char *linphone_conference_state_to_string(LinphoneConferenceState state);
/**
* Set a callback which will be called when the state of the conferenec is switching
* @param params A #LinphoneConferenceParams object
* @param cb The callback to call
* @param user_data Pointer to pass to the user_data parameter of #LinphoneConferenceStateChangedCb
*/
void linphone_conference_params_set_state_changed_callback(LinphoneConferenceParams *params, LinphoneConferenceStateChangedCb cb, void *user_data);
LinphoneConference *linphone_local_conference_new(LinphoneCore *core);
LinphoneConference *linphone_local_conference_new_with_params(LinphoneCore *core, const LinphoneConferenceParams *params);
LinphoneConference *linphone_remote_conference_new(LinphoneCore *core);
LinphoneConference *linphone_remote_conference_new_with_params(LinphoneCore *core, const LinphoneConferenceParams *params);
void linphone_conference_free(LinphoneConference *obj);
/**
* Get the state of a conference
*/
LinphoneConferenceState linphone_conference_get_state(const LinphoneConference *obj);
int linphone_conference_add_participant(LinphoneConference *obj, LinphoneCall *call);
int linphone_conference_remove_participant_with_call(LinphoneConference *obj, LinphoneCall *call);
......
......@@ -7461,18 +7461,30 @@ LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc) {
return lc->ringtoneplayer;
}
static void linphone_core_conference_state_changed(LinphoneConference *conf, LinphoneConferenceState cstate, void *user_data) {
LinphoneCore *lc = (LinphoneCore *)user_data;
if(cstate == LinphoneConferenceStartingFailed || cstate == LinphoneConferenceStopped) {
linphone_conference_free(lc->conf_ctx);
lc->conf_ctx = NULL;
}
}
LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc, const LinphoneConferenceParams *params) {
const char *conf_method_name;
if(lc->conf_ctx == NULL) {
LinphoneConferenceParams *params2 = linphone_conference_params_clone(params);
linphone_conference_params_set_state_changed_callback(params2, linphone_core_conference_state_changed, lc);
conf_method_name = lp_config_get_string(lc->config, "misc", "conference_type", "local");
if(strcasecmp(conf_method_name, "local") == 0) {
lc->conf_ctx = linphone_local_conference_new_with_params(lc, params);
lc->conf_ctx = linphone_local_conference_new_with_params(lc, params2);
} else if(strcasecmp(conf_method_name, "remote") == 0) {
lc->conf_ctx = linphone_remote_conference_new_with_params(lc, params);
lc->conf_ctx = linphone_remote_conference_new_with_params(lc, params2);
} else {
ms_error("'%s' is not a valid conference method", conf_method_name);
linphone_conference_params_free(params2);
return NULL;
}
linphone_conference_params_free(params2);
} else {
ms_error("Could not create a conference: a conference instance already exists");
return NULL;
......@@ -7482,7 +7494,12 @@ LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc
int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call) {
LinphoneConference *conference = linphone_core_get_conference(lc);
if(conference == NULL) conference = linphone_core_create_conference_with_params(lc, NULL);
if(conference == NULL) {
LinphoneConferenceParams *params = linphone_conference_params_new(lc);
linphone_conference_params_set_state_changed_callback(params, linphone_core_conference_state_changed, lc);
conference = linphone_core_create_conference_with_params(lc, params);
linphone_conference_params_free(params);
}
if(conference) return linphone_conference_add_participant(lc->conf_ctx, call);
else return -1;
}
......@@ -7508,7 +7525,10 @@ int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call) {
}
int linphone_core_terminate_conference(LinphoneCore *lc) {
if(lc->conf_ctx == NULL) return -1;
if(lc->conf_ctx == NULL) {
ms_error("Could not terminate conference: no conference context");
return -1;
}
linphone_conference_terminate(lc->conf_ctx);
linphone_conference_free(lc->conf_ctx);
lc->conf_ctx = NULL;
......
......@@ -258,6 +258,7 @@ typedef struct _LinphoneConferenceServer {
LinphoneCoreManager base;
LinphoneCall *first_call;
LinphoneCoreVTable *vtable;
LinphoneRegistrationState reg_state;
} LinphoneConferenceServer;
typedef struct _LinphoneCallTestParams {
......@@ -361,7 +362,7 @@ void liblinphone_tester_uninit(void);
int liblinphone_tester_set_log_file(const char *filename);
bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state);
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file);
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file, bool_t do_registration);
void linphone_conference_server_destroy(LinphoneConferenceServer *conf_srv);
extern const char *liblinphone_tester_mire_id;
......
......@@ -188,6 +188,7 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
LinphoneConference *conference;
const MSList* calls;
bool_t is_remote_conf;
bool_t focus_is_up = (focus && ((LinphoneConferenceServer *)focus)->reg_state == LinphoneRegistrationOk);
MSList* lcs=ms_list_append(NULL,marie->lc);
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,laure->lc);
......@@ -213,9 +214,21 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
if(!is_remote_conf) {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000));
} else {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,initial_marie_stat.number_of_LinphoneTransferCallConnected+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,initial_marie_stat.number_of_LinphoneCallEnd+1,5000));
if(focus_is_up) {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,initial_marie_stat.number_of_LinphoneTransferCallConnected+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,initial_marie_stat.number_of_LinphoneCallEnd+1,5000));
} else {
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallError, initial_marie_stat.number_of_LinphoneCallError+1, 5000));
BC_ASSERT_PTR_NULL(linphone_core_get_conference(marie->lc));
BC_ASSERT_EQUAL(linphone_core_terminate_conference(marie->lc), -1, int, "%d");
linphone_core_terminate_call(marie->lc, marie_call_pauline);
linphone_core_terminate_call(marie->lc, marie_call_laure);
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallEnd, initial_marie_stat.number_of_LinphoneCallEnd+2, 10000));
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEnd, initial_pauline_stat.number_of_LinphoneCallEnd+1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallEnd, initial_laure_stat.number_of_LinphoneCallEnd+1, 5000));
goto end;
}
}
linphone_core_add_to_conference(marie->lc,marie_call_pauline);
......@@ -267,11 +280,11 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
}
linphone_core_terminate_conference(marie->lc);
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,is_remote_conf?2:1,10000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,is_remote_conf?3:1,10000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,is_remote_conf?2:1,10000));
end:
ms_list_free(lcs);
}
......@@ -766,7 +779,38 @@ void simple_remote_conference(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
const char *laure_proxy_uri = linphone_proxy_config_get_server_addr(laure_proxy_config);
const char *focus_uri = linphone_proxy_config_get_identity(focus_proxy_config);
int laure_n_register = laure->stat.number_of_LinphoneRegistrationOk;
MSList *lcs = NULL;
lp_config_set_string(marie_config, "misc", "conference_type", "remote");
lp_config_set_string(marie_config, "misc", "conference_focus_addr", focus_uri);
linphone_proxy_config_edit(laure_proxy_config);
linphone_proxy_config_set_route(laure_proxy_config, laure_proxy_uri);
linphone_proxy_config_done(laure_proxy_config);
lcs = ms_list_append(lcs, laure->lc);
BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneRegistrationOk, laure_n_register+1, 5000));
ms_list_free(lcs);
simple_conference_base(marie, pauline, laure, (LinphoneCoreManager *)focus);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_conference_server_destroy(focus);
}
void simple_remote_conference_shut_down_focus(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", FALSE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
......@@ -797,7 +841,7 @@ void eject_from_3_participants_remote_conference(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
......@@ -840,7 +884,8 @@ test_t multi_call_tests[] = {
TEST_NO_TAG("Unattended call transfer with error", unattended_call_transfer_with_error),
TEST_NO_TAG("Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call),
TEST_NO_TAG("Simple remote conference", simple_remote_conference),
TEST_NO_TAG("Eject from 3 participants in remote conference", eject_from_3_participants_remote_conference)
TEST_NO_TAG("Simple remote conference with shut down focus", simple_remote_conference_shut_down_focus),
TEST_NO_TAG("Eject from 3 participants in remote conference", eject_from_3_participants_remote_conference),
};
test_suite_t multi_call_test_suite = {"Multi call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
......
......@@ -667,7 +667,7 @@ bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, Linph
return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_success : audio_success;
}
void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
static void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
LinphoneCoreVTable *vtable = linphone_core_get_current_vtable(lc);
LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)vtable->user_data;
......@@ -696,7 +696,7 @@ void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCal
}
}
void linphone_conference_server_refer_received(LinphoneCore *core, const char *refer_to) {
static void linphone_conference_server_refer_received(LinphoneCore *core, const char *refer_to) {
char method[20];
LinphoneAddress *refer_to_addr = linphone_address_new(refer_to);
char *uri;
......@@ -714,17 +714,30 @@ void linphone_conference_server_refer_received(LinphoneCore *core, const char *r
linphone_address_destroy(refer_to_addr);
}
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file) {
static void linphone_conference_server_registration_state_changed(LinphoneCore *core,
LinphoneProxyConfig *cfg,
LinphoneRegistrationState cstate,
const char *message) {
LinphoneCoreVTable *vtable = linphone_core_get_current_vtable(core);
LinphoneConferenceServer *m = (LinphoneConferenceServer *)linphone_core_v_table_get_user_data(vtable);
if(cfg == linphone_core_get_default_proxy_config(core)) {
m->reg_state = cstate;
}
}
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file, bool_t do_registration) {
LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)ms_new0(LinphoneConferenceServer, 1);
LinphoneCoreManager *lm = (LinphoneCoreManager *)conf_srv;
conf_srv->vtable = linphone_core_v_table_new();
conf_srv->vtable->call_state_changed = linphone_conference_server_call_state_changed;
conf_srv->vtable->refer_received = linphone_conference_server_refer_received;
conf_srv->vtable->registration_state_changed = linphone_conference_server_registration_state_changed;
conf_srv->vtable->user_data = conf_srv;
conf_srv->reg_state = LinphoneRegistrationNone;
linphone_core_manager_init(lm, rc_file);
linphone_core_add_listener(lm->lc, conf_srv->vtable);
linphone_core_manager_start(lm, TRUE);
linphone_core_manager_start(lm, do_registration);
return conf_srv;
}
......
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