diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 2b60a0f80..a5fcd21bb 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -703,7 +703,7 @@ static void call_with_ipv6(void) { static void file_transfer_message_rcs_to_external_body_client(void) { if (transport_supported(LinphoneTransportTls)) { - LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneChatRoom* chat_room; LinphoneChatMessage* message; LinphoneChatMessageCbs *cbs; @@ -712,13 +712,13 @@ static void file_transfer_message_rcs_to_external_body_client(void) { size_t file_size; char *send_filepath = bc_tester_res("images/nowebcamCIF.jpg"); char *receive_filepath = bc_tester_file("receive_file.dump"); - LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); - linphone_core_manager_start(marie, "marie_rc", TRUE); + linphone_core_manager_start(marie, TRUE); linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); - linphone_core_manager_start(pauline, "pauline_rc", TRUE); + linphone_core_manager_start(pauline, TRUE); reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -803,14 +803,14 @@ void send_file_transfer_message_using_external_body_url(LinphoneCoreManager *mar static void file_transfer_message_external_body_to_external_body_client(void) { if (transport_supported(LinphoneTransportTls)) { - LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); - linphone_core_manager_start(marie, "marie_rc", TRUE); + linphone_core_manager_start(marie, TRUE); linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp"); - linphone_core_manager_start(pauline, "pauline_rc", TRUE); + linphone_core_manager_start(pauline, TRUE); reset_counters(&marie->stat); reset_counters(&pauline->stat); @@ -827,14 +827,14 @@ static void file_transfer_message_external_body_to_external_body_client(void) { static void file_transfer_message_external_body_to_rcs_client(void) { if (transport_supported(LinphoneTransportTls)) { - LinphoneCoreManager* marie = linphone_core_manager_init( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_init( "pauline_rc"); + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); linphone_proxy_config_set_custom_header(marie->lc->default_proxy, "Accept", "application/sdp"); - linphone_core_manager_start(marie, "marie_rc", TRUE); + linphone_core_manager_start(marie, TRUE); linphone_proxy_config_set_custom_header(pauline->lc->default_proxy, "Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); - linphone_core_manager_start(pauline, "pauline_rc", TRUE); + linphone_core_manager_start(pauline, TRUE); reset_counters(&marie->stat); reset_counters(&pauline->stat); diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index 4cbe28046..1784ee54a 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -249,6 +249,12 @@ typedef struct _LinphoneCoreManager { int number_of_cunit_error_at_creation; } LinphoneCoreManager; +typedef struct _LinphoneConferenceServer { + LinphoneCoreManager base; + LinphoneCall *first_call; + LinphoneCoreVTable *vtable; +} LinphoneConferenceServer; + typedef struct _LinphoneCallTestParams { LinphoneCallParams *base; bool_t sdp_removal; @@ -258,11 +264,12 @@ typedef struct _LinphoneCallTestParams { void liblinphone_tester_add_suites(void); -LinphoneCoreManager* linphone_core_manager_init(const char* rc_file); -void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, int check_for_proxies); +void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file); +void linphone_core_manager_start(LinphoneCoreManager *mgr, int check_for_proxies); LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies); LinphoneCoreManager* linphone_core_manager_new(const char* rc_file); void linphone_core_manager_stop(LinphoneCoreManager *mgr); +void linphone_core_manager_uninit(LinphoneCoreManager *mgr); void linphone_core_manager_destroy(LinphoneCoreManager* mgr); void reset_counters( stats* counters); @@ -349,6 +356,9 @@ 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); +void linphone_conference_server_destroy(LinphoneConferenceServer *conf_srv); + extern const char *liblinphone_tester_mire_id; diff --git a/tester/multi_call_tester.c b/tester/multi_call_tester.c index c8021afc3..de6899892 100644 --- a/tester/multi_call_tester.c +++ b/tester/multi_call_tester.c @@ -177,7 +177,7 @@ static void incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_ incoming_call_accepted_when_outgoing_call_in_state(LinphoneCallOutgoingEarlyMedia); } -static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure) { +static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure, LinphoneCoreManager *focus) { stats initial_marie_stat; stats initial_pauline_stat; @@ -187,9 +187,14 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag LinphoneCall* pauline_called_by_marie; LinphoneCall* marie_call_laure; const MSList* calls; + bool_t is_remote_conf; MSList* lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,laure->lc); + if(focus) lcs=ms_list_append(lcs,focus->lc); + + is_remote_conf = (strcmp(lp_config_get_string(marie->lc->config, "misc", "conference_type", "local"), "remote") == 0); + if(is_remote_conf) BC_ASSERT_PTR_NOT_NULL(focus); BC_ASSERT_TRUE(call(marie,pauline)); marie_call_pauline=linphone_core_get_current_call(marie->lc); @@ -205,20 +210,35 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag BC_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); linphone_core_add_to_conference(marie->lc,marie_call_laure); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000)); + 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)); + } linphone_core_add_to_conference(marie->lc,marie_call_pauline); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); - + if(!is_remote_conf) { + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); + } else { + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,initial_marie_stat.number_of_LinphoneTransferCallConnected+2,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,initial_marie_stat.number_of_LinphoneCallEnd+2,5000)); + } + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000)); BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000)); BC_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); - BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3, int, "%d"); + BC_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),is_remote_conf?-1:3, int, "%d"); - BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + if(!is_remote_conf) { + BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + } else { + BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); + } BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(laure->lc)); @@ -241,9 +261,9 @@ 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,1,10000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); - BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + 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)); ms_list_free(lcs); } @@ -252,7 +272,7 @@ static void simple_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"); - simple_conference_base(marie,pauline,laure); + simple_conference_base(marie,pauline,laure, NULL); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(laure); @@ -299,7 +319,7 @@ static void simple_encrypted_conference_with_ice(LinphoneMediaEncryption mode) { linphone_core_set_media_encryption(pauline->lc,mode); linphone_core_set_media_encryption(laure->lc,mode); - simple_conference_base(marie,pauline,laure); + simple_conference_base(marie,pauline,laure,NULL); } else { ms_warning("No [%s] support available",linphone_media_encryption_to_string(mode)); BC_PASS("Passed"); @@ -695,22 +715,55 @@ static void eject_from_4_participants_conference(void) { linphone_core_manager_destroy(laure); linphone_core_manager_destroy(michelle); } + + +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"); + 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); +} test_t multi_call_tests[] = { { "Call waiting indication", call_waiting_indication }, { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, - { "Incoming call accepted when outgoing call in progress",incoming_call_accepted_when_outgoing_call_in_progress}, - { "Incoming call accepted when outgoing call in outgoing ringing",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing}, - { "Incoming call accepted when outgoing call in outgoing ringing early media",incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media}, + { "Incoming call accepted when outgoing call in progress", incoming_call_accepted_when_outgoing_call_in_progress}, + { "Incoming call accepted when outgoing call in outgoing ringing", incoming_call_accepted_when_outgoing_call_in_outgoing_ringing}, + { "Incoming call accepted when outgoing call in outgoing ringing early media", incoming_call_accepted_when_outgoing_call_in_outgoing_ringing_early_media}, { "Simple conference", simple_conference }, - { "Simple conference with ICE",simple_conference_with_ice}, + { "Simple conference with ICE", simple_conference_with_ice}, { "Simple ZRTP conference with ICE",simple_zrtp_conference_with_ice}, + { "Eject from 3 participants conference", eject_from_3_participants_conference }, + { "Eject from 4 participants conference", eject_from_4_participants_conference }, { "Simple call transfer", simple_call_transfer }, { "Unattended call transfer", unattended_call_transfer }, { "Unattended call transfer with error", unattended_call_transfer_with_error }, { "Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call }, - { "Eject from 3 participants conference", eject_from_3_participants_conference }, - { "Eject from 4 participants conference", eject_from_4_participants_conference }, + { "Simple remote conference", simple_remote_conference } }; test_suite_t multi_call_test_suite = {"Multi call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, diff --git a/tester/rcfiles/conference_focus_rc b/tester/rcfiles/conference_focus_rc new file mode 100644 index 000000000..c0cdd5aaa --- /dev/null +++ b/tester/rcfiles/conference_focus_rc @@ -0,0 +1,26 @@ +[sip] +default_proxy=0 +sip_port=-1 +sip_tcp_port=-1 +sip_dtls_port=-1 +sip_tls_port=-1 + +[rtp] +audio_rtp_port=18070-28000 +text_rtp_port=39000-49000 +video_rtp_port=28070-38000 + +[proxy_0] +reg_proxy=sip.example.org;transport=tcp +reg_route=sip.example.org;transport=tcp;lr +reg_identity="Focus" +reg_expires=3600 +reg_sendregister=1 +publish=0 + +[auth_info_0] +username=focus +userid=focus +passwd=secret +realm=sip.example.org + diff --git a/tester/tester.c b/tester/tester.c index ad3380993..c4bad5f9d 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -260,8 +260,7 @@ static void display_status(LinphoneCore *lc, const char *status){ ms_message("display_status(): %s",status); } -LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { - LinphoneCoreManager* mgr= ms_new0(LinphoneCoreManager,1); +void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file) { char *rc_path = NULL; char *hellopath = bc_tester_res("sounds/hello8000.wav"); mgr->number_of_cunit_error_at_creation = CU_get_number_of_failures(); @@ -330,16 +329,14 @@ LinphoneCoreManager* linphone_core_manager_init(const char* rc_file) { linphone_core_set_user_certificates_path(mgr->lc,bc_tester_get_writable_dir_prefix()); if (rc_path) ms_free(rc_path); - - return mgr; } -void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, int check_for_proxies) { +void linphone_core_manager_start(LinphoneCoreManager *mgr, int check_for_proxies) { LinphoneProxyConfig* proxy; int proxy_count; /*BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count, int, "%d");*/ - if (check_for_proxies && rc_file) /**/ + if (check_for_proxies) /**/ proxy_count=ms_list_size(linphone_core_get_proxy_config_list(mgr->lc)); else proxy_count=0; @@ -363,14 +360,16 @@ void linphone_core_manager_start(LinphoneCoreManager *mgr, const char* rc_file, } LinphoneCoreManager* linphone_core_manager_new( const char* rc_file) { - LinphoneCoreManager *manager = linphone_core_manager_init(rc_file); - linphone_core_manager_start(manager, rc_file, TRUE); + LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); + linphone_core_manager_init(manager, rc_file); + linphone_core_manager_start(manager, TRUE); return manager; } LinphoneCoreManager* linphone_core_manager_new2( const char* rc_file, int check_for_proxies) { - LinphoneCoreManager *manager = linphone_core_manager_init(rc_file); - linphone_core_manager_start(manager, rc_file, check_for_proxies); + LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); + linphone_core_manager_init(manager, rc_file); + linphone_core_manager_start(manager, check_for_proxies); return manager; } @@ -381,7 +380,7 @@ void linphone_core_manager_stop(LinphoneCoreManager *mgr){ } } -void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { +void linphone_core_manager_uninit(LinphoneCoreManager *mgr) { if (mgr->stat.last_received_chat_message) { linphone_chat_message_unref(mgr->stat.last_received_chat_message); } @@ -406,8 +405,12 @@ void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { if (mgr->identity) { linphone_address_destroy(mgr->identity); } + manager_count--; +} +void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { + linphone_core_manager_uninit(mgr); ms_free(mgr); } @@ -668,4 +671,50 @@ 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) { + LinphoneCoreVTable *vtable = linphone_core_get_current_vtable(lc); + LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)vtable->user_data; + + switch(cstate) { + case LinphoneCallIncomingReceived: + linphone_core_accept_call(lc, call); + break; + + case LinphoneCallStreamsRunning: + if(linphone_call_get_conference(call) == NULL) { + linphone_core_add_to_conference(lc, call); + linphone_core_leave_conference(lc); + if(conf_srv->first_call == NULL) conf_srv->first_call = linphone_call_ref(call); + } + break; + + case LinphoneCallEnd: + if(call == conf_srv->first_call) { + linphone_core_terminate_conference(lc); + linphone_call_unref(call); + conf_srv->first_call = NULL; + } + break; + + default: break; + } +} +LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file) { + 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->user_data = conf_srv; + linphone_core_manager_init(lm, rc_file); + linphone_core_add_listener(lm->lc, conf_srv->vtable); + linphone_core_manager_start(lm, TRUE); + return conf_srv; +} + +void linphone_conference_server_destroy(LinphoneConferenceServer *conf_srv) { + linphone_core_manager_uninit((LinphoneCoreManager *)conf_srv); + linphone_core_v_table_destroy(conf_srv->vtable); + ms_free(conf_srv); +}