diff --git a/.cproject b/.cproject index 5fb15ef62..8f37d4ae1 100644 --- a/.cproject +++ b/.cproject @@ -1,7 +1,5 @@ - - - + @@ -44,6 +42,7 @@ + diff --git a/tester/Makefile.am b/tester/Makefile.am index c55c992e3..9e5731950 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -29,7 +29,8 @@ liblinphonetester_la_SOURCES = tester.c \ dtmf_tester.c \ accountmanager.c \ offeranswer_tester.c \ - video_tester.c + video_tester.c \ + multi_call.c liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) diff --git a/tester/call_tester.c b/tester/call_tester.c index 9cdc7dcdd..03276cc96 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1242,7 +1242,7 @@ static void call_paused_resumed_with_loss(void) { linphone_core_manager_destroy(pauline); } -static bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2) { +bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2) { stats initial_call_stat_1=mgr_1->stat; stats initial_call_stat_2=mgr_2->stat; linphone_core_pause_call(mgr_1->lc,call_1); @@ -3722,6 +3722,18 @@ void static call_state_changed_2(LinphoneCore *lc, LinphoneCall *call, LinphoneC linphone_core_set_sip_transports(lc,&sip_tr); } } +void static call_state_changed_3(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ +/*just to check multi listener in such situation*/ + char* to=linphone_address_as_string(linphone_call_get_call_log(call)->to); + char* from=linphone_address_as_string(linphone_call_get_call_log(call)->from); + ms_message("Third call listener reports: %s call from [%s] to [%s], new state is [%s]" ,linphone_call_get_call_log(call)->dir==LinphoneCallIncoming?"Incoming":"Outgoing" + ,from + ,to + ,linphone_call_state_to_string(cstate)); + ms_free(to); + ms_free(from); +} + static void call_with_transport_change_base(bool_t succesfull_call) { int begin; @@ -3737,6 +3749,9 @@ static void call_with_transport_change_base(bool_t succesfull_call) { marie = linphone_core_manager_new("marie_rc"); pauline = linphone_core_manager_new( "pauline_rc"); linphone_core_add_listener(marie->lc,v_table); + v_table = linphone_core_v_table_new(); + v_table->call_state_changed=call_state_changed_3; + linphone_core_add_listener(marie->lc,v_table); sip_tr.udp_port = 0; sip_tr.tcp_port = 45875; @@ -3844,14 +3859,6 @@ test_t call_tests[] = { { "Call rejected because of wrong credential", call_rejected_because_wrong_credentials}, { "Call rejected without 403 because of wrong credential", call_rejected_without_403_because_wrong_credentials}, { "Call rejected without 403 because of wrong credential and no auth req cb", call_rejected_without_403_because_wrong_credentials_no_auth_req_cb}, - { "Call waiting indication", call_waiting_indication }, - { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, - { "Simple conference", simple_conference }, - { "Simple conference with ICE",simple_conference_with_ice}, - { "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 }, { "Call with ICE", call_with_ice }, { "Call with ICE without SDP", call_with_ice_no_sdp }, { "Call with ICE (random ports)", call_with_ice_random_ports }, @@ -3882,7 +3889,7 @@ test_t call_tests[] = { }; test_suite_t call_test_suite = { - "Call", + "Single Call", NULL, NULL, sizeof(call_tests) / sizeof(call_tests[0]), diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index c140a6453..1e8fb9a93 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -68,6 +68,7 @@ extern test_suite_t dtmf_test_suite; extern test_suite_t offeranswer_test_suite; extern test_suite_t video_test_suite; extern test_suite_t multicast_call_test_suite; +extern test_suite_t multi_call_test_suite; extern int liblinphone_tester_nb_test_suites(void); @@ -326,5 +327,7 @@ void linphone_call_cb(LinphoneCall *call,void * user_data); void call_paused_resumed_base(bool_t multicast); void simple_call_base(bool_t enable_multicast_recv_side); void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy,bool_t enable_tunnel); +bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params); +bool_t pause_call_1(LinphoneCoreManager* mgr_1,LinphoneCall* call_1,LinphoneCoreManager* mgr_2,LinphoneCall* call_2); #endif /* LIBLINPHONE_TESTER_H_ */ diff --git a/tester/multi_call.c b/tester/multi_call.c new file mode 100644 index 000000000..14f0db9d1 --- /dev/null +++ b/tester/multi_call.c @@ -0,0 +1,449 @@ +/* + 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 +#include +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "lpconfig.h" +#include "private.h" +#include "liblinphone_tester.h" +#include "mediastreamer2/msutils.h" +#include "belle-sip/sipstack.h" + +#ifdef WIN32 +#define unlink _unlink +#endif + + +static void call_waiting_indication_with_param(bool_t enable_caller_privacy) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + MSList *iterator; + MSList* lcs; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* pauline_called_by_laure=NULL; + LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc); + LinphoneCallParams *marie_params=linphone_core_create_default_call_parameters(marie->lc); + + if (enable_caller_privacy) + linphone_call_params_set_privacy(marie_params,LinphonePrivacyId); + + lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + CU_ASSERT_TRUE(call_with_caller_params(marie,pauline,marie_params)); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + + if (enable_caller_privacy) + linphone_call_params_set_privacy(laure_params,LinphonePrivacyId); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(laure->lc,pauline->identity,laure_params)); + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&pauline->stat.number_of_LinphoneCallIncomingReceived + ,2)); + + CU_ASSERT_EQUAL(laure->stat.number_of_LinphoneCallOutgoingProgress,1); + + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&laure->stat.number_of_LinphoneCallOutgoingRinging + ,1)); + + for (iterator=(MSList *)linphone_core_get_calls(pauline->lc);iterator!=NULL;iterator=iterator->next) { + LinphoneCall *call=(LinphoneCall *)iterator->data; + if (call != pauline_called_by_marie) { + /*fine, this is the call waiting*/ + pauline_called_by_laure=call; + linphone_core_accept_call(pauline->lc,pauline_called_by_laure); + } + } + + CU_ASSERT_TRUE(wait_for(laure->lc + ,pauline->lc + ,&laure->stat.number_of_LinphoneCallConnected + ,1)); + + CU_ASSERT_TRUE(wait_for(pauline->lc + ,marie->lc + ,&marie->stat.number_of_LinphoneCallPausedByRemote + ,1)); + + if (pauline_called_by_laure && enable_caller_privacy ) + CU_ASSERT_EQUAL(linphone_call_params_get_privacy(linphone_call_get_current_params(pauline_called_by_laure)),LinphonePrivacyId); + /*wait a bit for ACK to be sent*/ + wait_for_list(lcs,NULL,0,1000); + linphone_core_terminate_all_calls(pauline->lc); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} +static void call_waiting_indication(void) { + call_waiting_indication_with_param(FALSE); +} + +static void call_waiting_indication_with_privacy(void) { + call_waiting_indication_with_param(TRUE); +} + +static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManager* pauline, LinphoneCoreManager* laure) { + + stats initial_marie_stat; + stats initial_pauline_stat; + stats initial_laure_stat; + + LinphoneCall* marie_call_pauline; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* marie_call_laure; + + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + CU_ASSERT_TRUE(call(marie,pauline)); + marie_call_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + CU_ASSERT_TRUE(call(marie,laure)); + initial_marie_stat=marie->stat; + initial_pauline_stat=pauline->stat; + initial_laure_stat=laure->stat; + + marie_call_laure=linphone_core_get_current_call(marie->lc); + + CU_ASSERT_PTR_NOT_NULL_FATAL(marie_call_laure); + linphone_core_add_to_conference(marie->lc,marie_call_laure); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000)); + + linphone_core_add_to_conference(marie->lc,marie_call_pauline); + + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallResuming,initial_marie_stat.number_of_LinphoneCallResuming+1,2000)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,initial_pauline_stat.number_of_LinphoneCallStreamsRunning+1,5000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,initial_laure_stat.number_of_LinphoneCallStreamsRunning+1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+2,3000)); + + CU_ASSERT_TRUE(linphone_core_is_in_conference(marie->lc)); + CU_ASSERT_EQUAL(linphone_core_get_conference_size(marie->lc),3); + + /* + * FIXME: check_ice cannot work as it is today because there is no current call for the party that hosts the conference + if (linphone_core_get_firewall_policy(marie->lc) == LinphonePolicyUseIce) { + if (linphone_core_get_firewall_policy(pauline->lc) == LinphonePolicyUseIce) { + check_ice(marie,pauline,LinphoneIceStateHostConnection); + } + if (linphone_core_get_firewall_policy(laure->lc) == LinphonePolicyUseIce) { + check_ice(marie,laure,LinphoneIceStateHostConnection); + } + } + */ + + linphone_core_terminate_conference(marie->lc); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,10000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,10000)); + + + + ms_list_free(lcs); +} +static void simple_conference(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + simple_conference_base(marie,pauline,laure); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + +static void simple_conference_with_ice(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + + linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc,"stun.linphone.org"); + linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(pauline->lc,"stun.linphone.org"); + linphone_core_set_firewall_policy(laure->lc,LinphonePolicyUseIce); + linphone_core_set_stun_server(laure->lc,"stun.linphone.org"); + + simple_conference_base(marie,pauline,laure); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); +} + + +static void simple_call_transfer(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* pauline_called_by_marie; + LinphoneCall *marie_calling_pauline; + LinphoneCall *marie_calling_laure; + + char* laure_identity=linphone_address_as_string(laure->identity); + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + + CU_ASSERT_TRUE(call(marie,pauline)); + marie_calling_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + + linphone_core_transfer_call(pauline->lc,pauline_called_by_marie,laure_identity); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallRefered,1,2000)); + /*marie pausing pauline*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPausing,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausedByRemote,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000)); + /*marie calling laure*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + + CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); + linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + + marie_calling_laure=linphone_core_get_current_call(marie->lc); + CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure); + CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000)); + + /*terminate marie to pauline call*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,2000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +static void unattended_call_transfer(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* pauline_called_by_marie; + + char* laure_identity=linphone_address_as_string(laure->identity); + MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + + CU_ASSERT_TRUE(call(marie,pauline)); + pauline_called_by_marie=linphone_core_get_current_call(marie->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + linphone_core_transfer_call(marie->lc,pauline_called_by_marie,laure_identity); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*marie ends the call */ + linphone_core_terminate_call(marie->lc,pauline_called_by_marie); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + + /*Pauline starts the transfer*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +static void unattended_call_transfer_with_error(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* pauline_called_by_marie; + bool_t call_ok=TRUE; + MSList* lcs=ms_list_append(NULL,marie->lc); + + lcs=ms_list_append(lcs,pauline->lc); + + CU_ASSERT_TRUE((call_ok=call(marie,pauline))); + if (call_ok){ + pauline_called_by_marie=linphone_core_get_current_call(marie->lc); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + + linphone_core_transfer_call(marie->lc,pauline_called_by_marie,"unknown_user"); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*Pauline starts the transfer*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000)); + /* and immediately get an error*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000)); + + /*the error must be reported back to marie*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000)); + + /*and pauline should resume the call automatically*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000)); + + /*and call should be resumed*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + ms_list_free(lcs); +} + + +static void call_transfer_existing_call_outgoing_call(void) { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); + LinphoneCall* marie_call_pauline; + LinphoneCall* pauline_called_by_marie; + LinphoneCall* marie_call_laure; + LinphoneCall* laure_called_by_marie; + LinphoneCall* lcall; + bool_t call_ok=TRUE; + const MSList* calls; + MSList* lcs=ms_list_append(NULL,marie->lc); + + lcs=ms_list_append(lcs,pauline->lc); + lcs=ms_list_append(lcs,laure->lc); + + /*marie call pauline*/ + CU_ASSERT_TRUE((call_ok=call(marie,pauline))); + if (call_ok){ + marie_call_pauline=linphone_core_get_current_call(marie->lc); + pauline_called_by_marie=linphone_core_get_current_call(pauline->lc); + /*marie pause pauline*/ + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_pauline,pauline,pauline_called_by_marie)); + + /*marie call laure*/ + CU_ASSERT_TRUE(call(marie,laure)); + marie_call_laure=linphone_core_get_current_call(marie->lc); + laure_called_by_marie=linphone_core_get_current_call(laure->lc); + /*marie pause laure*/ + CU_ASSERT_TRUE(pause_call_1(marie,marie_call_laure,laure,laure_called_by_marie)); + + reset_counters(&marie->stat); + reset_counters(&pauline->stat); + reset_counters(&laure->stat); + + + linphone_core_transfer_call_to_another(marie->lc,marie_call_pauline,marie_call_laure); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + + /*pauline pausing marie*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,4000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,4000)); + /*pauline calling laure*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingProgress,1,2000)); + + /*laure accept call*/ + for(calls=linphone_core_get_calls(laure->lc);calls!=NULL;calls=calls->next) { + lcall = (LinphoneCall*)calls->data; + if (linphone_call_get_state(lcall) == LinphoneCallIncomingReceived) { + CU_ASSERT_EQUAL(linphone_call_get_replaced_call(lcall),laure_called_by_marie); + linphone_core_accept_call(laure->lc,lcall); + break; + } + } + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallStreamsRunning,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,1,2000)); + + /*terminate marie to pauline/laure call*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,2,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,1,2000)); + } + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(laure); + ms_list_free(lcs); +} + +test_t multi_call_tests[] = { + { "Call waiting indication", call_waiting_indication }, + { "Call waiting indication with privacy", call_waiting_indication_with_privacy }, + { "Simple conference", simple_conference }, + { "Simple conference with ICE",simple_conference_with_ice}, + { "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 } +}; + +test_suite_t multi_call_test_suite = { + "Multi call", + NULL, + NULL, + sizeof(multi_call_tests) / sizeof(multi_call_tests[0]), + multi_call_tests +}; diff --git a/tester/tester.c b/tester/tester.c index aadfbee83..f7c703e41 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -459,6 +459,7 @@ void liblinphone_tester_init(void) { add_test_suite(®ister_test_suite); add_test_suite(&offeranswer_test_suite); add_test_suite(&call_test_suite); + add_test_suite(&multi_call_test_suite); add_test_suite(&message_test_suite); add_test_suite(&presence_test_suite); #ifdef UPNP @@ -572,7 +573,11 @@ int liblinphone_tester_run_tests(const char *suite_name, const char *test_name) ms_warning("Tester compiled without CU_get_suite() function, running all tests instead of suite '%s'\n", suite_name); } #else - if (suite_name){ + if (!test_name && suite_name && strcmp("Call",suite_name) == 0) { + /*special case for suite Call which is now splitted into simple and multi*/ + CU_run_suite(CU_get_suite("Single call")); + CU_run_suite(CU_get_suite("Multi call")); + } else if (suite_name){ CU_pSuite suite; suite=CU_get_suite(suite_name); if (!suite) {