call_single_tester.c 284 KB
Newer Older
jehan's avatar
jehan committed
1
/*
2 3
	liblinphone_tester - liblinphone test suite
	Copyright (C) 2013  Belledonne Communications SARL
jehan's avatar
jehan committed
4

5 6 7 8
	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.
jehan's avatar
jehan committed
9

10 11 12 13
	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.
jehan's avatar
jehan committed
14

15 16
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
jehan's avatar
jehan committed
17
*/
18

Simon Morlat's avatar
Simon Morlat committed
19

20
#include <sys/types.h>
21
#include <sys/stat.h>
22 23
#include "linphone/core.h"
#include "linphone/lpconfig.h"
jehan's avatar
jehan committed
24 25
#include "private.h"
#include "liblinphone_tester.h"
Simon Morlat's avatar
Simon Morlat committed
26
#include "mediastreamer2/msutils.h"
jehan's avatar
jehan committed
27
#include "belle-sip/sipstack.h"
28
#include <bctoolbox/defs.h>
29

30
#ifdef _WIN32
31
#define unlink _unlink
Ghislain MARY's avatar
Ghislain MARY committed
32 33 34
#ifndef F_OK
#define F_OK 00 /*visual studio does not define F_OK*/
#endif
35
#endif
jehan's avatar
jehan committed
36

37
static void srtp_call(void);
jehan's avatar
jehan committed
38

39
// prototype definition for call_recording()
40
#ifdef __ANDROID__
41
#ifdef HAVE_OPENH264
Simon Morlat's avatar
Simon Morlat committed
42
extern void libmsopenh264_init(MSFactory *factory);
43 44 45
#endif
#endif

46

jehan's avatar
jehan committed
47 48 49
void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){
	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);
50
	stats* counters;
jehan's avatar
jehan committed
51 52 53 54
	ms_message(" %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));
jehan's avatar
jehan committed
55 56
	ms_free(to);
	ms_free(from);
57
	counters = get_stats(lc);
jehan's avatar
jehan committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
	switch (cstate) {
	case LinphoneCallIncomingReceived:counters->number_of_LinphoneCallIncomingReceived++;break;
	case LinphoneCallOutgoingInit :counters->number_of_LinphoneCallOutgoingInit++;break;
	case LinphoneCallOutgoingProgress :counters->number_of_LinphoneCallOutgoingProgress++;break;
	case LinphoneCallOutgoingRinging :counters->number_of_LinphoneCallOutgoingRinging++;break;
	case LinphoneCallOutgoingEarlyMedia :counters->number_of_LinphoneCallOutgoingEarlyMedia++;break;
	case LinphoneCallConnected :counters->number_of_LinphoneCallConnected++;break;
	case LinphoneCallStreamsRunning :counters->number_of_LinphoneCallStreamsRunning++;break;
	case LinphoneCallPausing :counters->number_of_LinphoneCallPausing++;break;
	case LinphoneCallPaused :counters->number_of_LinphoneCallPaused++;break;
	case LinphoneCallResuming :counters->number_of_LinphoneCallResuming++;break;
	case LinphoneCallRefered :counters->number_of_LinphoneCallRefered++;break;
	case LinphoneCallError :counters->number_of_LinphoneCallError++;break;
	case LinphoneCallEnd :counters->number_of_LinphoneCallEnd++;break;
	case LinphoneCallPausedByRemote :counters->number_of_LinphoneCallPausedByRemote++;break;
	case LinphoneCallUpdatedByRemote :counters->number_of_LinphoneCallUpdatedByRemote++;break;
	case LinphoneCallIncomingEarlyMedia :counters->number_of_LinphoneCallIncomingEarlyMedia++;break;
	case LinphoneCallUpdating :counters->number_of_LinphoneCallUpdating++;break;
	case LinphoneCallReleased :counters->number_of_LinphoneCallReleased++;break;
77 78
	case LinphoneCallEarlyUpdating: counters->number_of_LinphoneCallEarlyUpdating++;break;
	case LinphoneCallEarlyUpdatedByRemote: counters->number_of_LinphoneCallEarlyUpdatedByRemote++;break;
jehan's avatar
jehan committed
79
	default:
80
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
81 82
	}
}
83

84 85 86 87 88 89 90 91 92
static bool_t rtcp_is_type(const mblk_t *m, rtcp_type_t type){
	const rtcp_common_header_t *ch=rtcp_get_common_header(m);
	return (ch!=NULL && rtcp_common_header_get_packet_type(ch)==type);
}

static void rtcp_received(stats* counters, mblk_t *packet) {
	do{
		if (rtcp_is_type(packet, RTCP_RTPFB)){
			if (rtcp_RTPFB_get_type(packet) ==  RTCP_RTPFB_TMMBR) {
93
				counters->number_of_tmmbr_received++;
94 95 96 97 98 99 100
				counters->last_tmmbr_value_received = (int)rtcp_RTPFB_tmmbr_get_max_bitrate(packet);
			}
		}
	}while (rtcp_next_packet(packet));
	rtcp_rewind(packet);
}

101 102
void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) {
	stats* counters = get_stats(lc);
103
	counters->number_of_LinphoneCallStatsUpdated++;
104
	if (lstats->updated & LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) {
105
		counters->number_of_rtcp_received++;
106 107 108
		if (lstats->rtcp_received_via_mux){
			counters->number_of_rtcp_received_via_mux++;
		}
109
		rtcp_received(counters, lstats->received_rtcp);
110 111
	}
	if (lstats->updated & LINPHONE_CALL_STATS_SENT_RTCP_UPDATE ) {
112 113
		counters->number_of_rtcp_sent++;
	}
114 115
	if (lstats->updated & LINPHONE_CALL_STATS_PERIODICAL_UPDATE ) {
		int tab_size = sizeof (counters->audio_download_bandwidth)/sizeof(int);
116
		int index = (counters->current_bandwidth_index[lstats->type]++) % tab_size;
117 118 119
		LinphoneCallStats *audio_stats, *video_stats;
		audio_stats = linphone_call_get_audio_stats(call);
		video_stats = linphone_call_get_video_stats(call);
120
		if (lstats->type == LINPHONE_CALL_STATS_AUDIO) {
121 122
			counters->audio_download_bandwidth[index] = (int)audio_stats->download_bandwidth;
			counters->audio_upload_bandwidth[index] = (int)audio_stats->upload_bandwidth;
123
		} else {
124 125
			counters->video_download_bandwidth[index] = (int)video_stats->download_bandwidth;
			counters->video_upload_bandwidth[index] = (int)video_stats->upload_bandwidth;
126
		}
127 128
		linphone_call_stats_unref(audio_stats);
		linphone_call_stats_unref(video_stats);
129
	}
130

131 132
}

133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
void linphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) {
	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);
	stats* counters;
	ms_message(" %s call from [%s] to [%s], is now [%s]",linphone_call_get_call_log(call)->dir==LinphoneCallIncoming?"Incoming":"Outgoing"
														,from
														,to
														,(on?"encrypted":"unencrypted"));
	ms_free(to);
	ms_free(from);
	counters = get_stats(lc);
	if (on)
		counters->number_of_LinphoneCallEncryptedOn++;
	else
		counters->number_of_LinphoneCallEncryptedOff++;
}
johan's avatar
johan committed
149

jehan's avatar
jehan committed
150 151 152
void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) {
	char* to=linphone_address_as_string(linphone_call_get_call_log(transfered)->to);
	char* from=linphone_address_as_string(linphone_call_get_call_log(transfered)->from);
153
	stats* counters;
jehan's avatar
jehan committed
154 155 156 157
	ms_message("Transferred call from [%s] to [%s], new state is [%s]",from,to,linphone_call_state_to_string(new_call_state));
	ms_free(to);
	ms_free(from);

158
	counters = get_stats(lc);
jehan's avatar
jehan committed
159
	switch (new_call_state) {
jehan's avatar
jehan committed
160
	case LinphoneCallOutgoingInit :counters->number_of_LinphoneTransferCallOutgoingInit++;break;
161 162 163 164 165
	case LinphoneCallOutgoingProgress :counters->number_of_LinphoneTransferCallOutgoingProgress++;break;
	case LinphoneCallOutgoingRinging :counters->number_of_LinphoneTransferCallOutgoingRinging++;break;
	case LinphoneCallOutgoingEarlyMedia :counters->number_of_LinphoneTransferCallOutgoingEarlyMedia++;break;
	case LinphoneCallConnected :counters->number_of_LinphoneTransferCallConnected++;break;
	case LinphoneCallStreamsRunning :counters->number_of_LinphoneTransferCallStreamsRunning++;break;
166
	case LinphoneCallError :counters->number_of_LinphoneTransferCallError++;break;
jehan's avatar
jehan committed
167
	default:
168
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
169 170
	}
}
171

jehan's avatar
jehan committed
172

Simon Morlat's avatar
Simon Morlat committed
173
void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) {
jehan's avatar
jehan committed
174 175
	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);
176
	stats* counters;
jehan's avatar
jehan committed
177 178 179 180
	LinphoneCore* lc=(LinphoneCore*)user_data;
	ms_message("call from [%s] to [%s] receive iFrame",from,to);
	ms_free(to);
	ms_free(from);
181
	counters = (stats*)get_stats(lc);
jehan's avatar
jehan committed
182 183
	counters->number_of_IframeDecoded++;
}
Simon Morlat's avatar
Simon Morlat committed
184

Simon Morlat's avatar
Simon Morlat committed
185
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) {
186
	LinphoneCall *c1,*c2;
Simon Morlat's avatar
Simon Morlat committed
187
	MSTimeSpec ts;
jehan's avatar
jehan committed
188
	int max_time_to_wait;
189
	LinphoneCallStats *audio_stats1, *video_stats1, *audio_stats2, *video_stats2;
190 191
	c1=linphone_core_get_current_call(caller->lc);
	c2=linphone_core_get_current_call(callee->lc);
192

193 194
	BC_ASSERT_PTR_NOT_NULL(c1);
	BC_ASSERT_PTR_NOT_NULL(c2);
195

Simon Morlat's avatar
Simon Morlat committed
196
	if (!c1 || !c2) return;
jehan's avatar
jehan committed
197 198
	linphone_call_ref(c1);
	linphone_call_ref(c2);
Simon Morlat's avatar
Simon Morlat committed
199
	liblinphone_tester_clock_start(&ts);
jehan's avatar
jehan committed
200 201 202 203
	if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc))
		max_time_to_wait = 15000;
	else
		max_time_to_wait = 5000;
204

Simon Morlat's avatar
Simon Morlat committed
205
	do {
206 207 208 209 210 211 212 213
		audio_stats1 = linphone_call_get_audio_stats(c1);
		video_stats1 = linphone_call_get_video_stats(c1);
		audio_stats2 = linphone_call_get_audio_stats(c2);
		video_stats2 = linphone_call_get_video_stats(c2);
		if (audio_stats1->round_trip_delay > 0.0
			&& audio_stats2->round_trip_delay > 0.0
			&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || video_stats1->round_trip_delay>0.0)
			&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2))  || video_stats2->round_trip_delay>0.0)) {
214
			break;
215

216
		}
217 218 219 220
		linphone_call_stats_unref(audio_stats1);
		linphone_call_stats_unref(audio_stats2);
		if (video_stats1) linphone_call_stats_unref(video_stats1);
		if (video_stats2) linphone_call_stats_unref(video_stats2);
221
		wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/
jehan's avatar
jehan committed
222
	}while (!liblinphone_tester_clock_elapsed(&ts,max_time_to_wait));
223

224 225 226 227
	audio_stats1 = linphone_call_get_audio_stats(c1);
	video_stats1 = linphone_call_get_video_stats(c1);
	audio_stats2 = linphone_call_get_audio_stats(c2);
	video_stats2 = linphone_call_get_video_stats(c2);
jehan's avatar
jehan committed
228
	if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc)) {
229 230
		BC_ASSERT_GREATER(caller->stat.number_of_rtcp_received, 1, int, "%i");
		BC_ASSERT_GREATER(callee->stat.number_of_rtcp_received, 1, int, "%i");
231 232
		BC_ASSERT_GREATER(audio_stats1->round_trip_delay,0.0,float,"%f");
		BC_ASSERT_GREATER(audio_stats2->round_trip_delay,0.0,float,"%f");
jehan's avatar
jehan committed
233
		if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
234
			BC_ASSERT_GREATER(video_stats1->round_trip_delay,0.0,float,"%f");
jehan's avatar
jehan committed
235 236
		}
		if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
237
			BC_ASSERT_GREATER(video_stats2->round_trip_delay,0.0,float,"%f");
jehan's avatar
jehan committed
238 239 240
		}
	} else {
		if (linphone_core_rtcp_enabled(caller->lc)) {
241 242
			BC_ASSERT_EQUAL(audio_stats1->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu");
			BC_ASSERT_EQUAL(audio_stats2->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
243
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
244
				BC_ASSERT_EQUAL(video_stats1->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
245 246
			}
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
247
				BC_ASSERT_EQUAL(video_stats2->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
248 249 250
			}
		}
		if (linphone_core_rtcp_enabled(callee->lc)) {
251 252
		BC_ASSERT_EQUAL(audio_stats2->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu");
		BC_ASSERT_EQUAL(audio_stats1->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
253
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
254
				BC_ASSERT_EQUAL(video_stats1->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
255 256
			}
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
257
				BC_ASSERT_EQUAL(video_stats2->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu");
jehan's avatar
jehan committed
258 259 260
			}
		}

261
	}
jehan's avatar
jehan committed
262 263
	linphone_call_unref(c1);
	linphone_call_unref(c2);
264 265
}

266 267 268 269 270 271 272 273
static void setup_sdp_handling(const LinphoneCallTestParams* params, LinphoneCoreManager* mgr ){
	if( params->sdp_removal ){
		sal_default_set_sdp_handling(mgr->lc->sal, SalOpSDPSimulateRemove);
	} else if( params->sdp_simulate_error ){
		sal_default_set_sdp_handling(mgr->lc->sal, SalOpSDPSimulateError);
	}
}

274 275 276 277 278 279 280 281
/*
 * CAUTION this function is error prone. you should not use it anymore in new tests.
 * Creating callee call params before the call is actually received is not the good way
 * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing
 * the call object for which params are to be created.
 * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how
 * callee params will be set by linphone_core_create_call_params().
 * This function was developped at a time where the use of the API about incoming params was not yet clarified.
282
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
283 284
 * it is not a so good idea to build new tests based on this function.
**/
285
bool_t call_with_params2(LinphoneCoreManager* caller_mgr
286
						,LinphoneCoreManager* callee_mgr
287 288 289
						, const LinphoneCallTestParams *caller_test_params
						, const LinphoneCallTestParams *callee_test_params
						, bool_t build_callee_params) {
jehan's avatar
jehan committed
290
	int retry=0;
jehan's avatar
jehan committed
291 292
	stats initial_caller=caller_mgr->stat;
	stats initial_callee=callee_mgr->stat;
jehan's avatar
jehan committed
293
	bool_t result=FALSE;
294 295
	LinphoneCallParams *caller_params = caller_test_params->base;
	LinphoneCallParams *callee_params = callee_test_params->base;
296
	bool_t did_receive_call;
297
	LinphoneCall *callee_call=NULL;
298
	LinphoneCall *caller_call=NULL;
299

300 301 302 303
	/* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */
	linphone_core_manager_wait_for_stun_resolution(caller_mgr);
	linphone_core_manager_wait_for_stun_resolution(callee_mgr);

304 305
	setup_sdp_handling(caller_test_params, caller_mgr);
	setup_sdp_handling(callee_test_params, callee_mgr);
306

307
	if (!caller_params){
308
		BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity)));
Simon Morlat's avatar
Simon Morlat committed
309
	}else{
310
		BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params)));
Simon Morlat's avatar
Simon Morlat committed
311
	}
312

313
	BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(caller_call)); /*assert that remote params are NULL when no response is received yet*/
jehan's avatar
jehan committed
314

315
	did_receive_call = wait_for(callee_mgr->lc
316 317 318
				,caller_mgr->lc
				,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
				,initial_callee.number_of_LinphoneCallIncomingReceived+1);
319
	BC_ASSERT_EQUAL(did_receive_call, !callee_test_params->sdp_simulate_error, int, "%d");
320

321 322
	sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal);
	sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal);
323

324
	if (!did_receive_call) return 0;
325 326


327
	if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
328 329
		BC_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc));
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d");
jehan's avatar
jehan committed
330

jehan's avatar
jehan committed
331

jehan's avatar
jehan committed
332 333
	while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging!=(initial_caller.number_of_LinphoneCallOutgoingRinging + 1)
			&& caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia!=(initial_caller.number_of_LinphoneCallOutgoingEarlyMedia +1)
334
			&& retry++ < 100) {
jehan's avatar
jehan committed
335 336
			linphone_core_iterate(caller_mgr->lc);
			linphone_core_iterate(callee_mgr->lc);
337
			ms_usleep(20000);
jehan's avatar
jehan committed
338 339 340
	}


341
	BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1)
Simon Morlat's avatar
Simon Morlat committed
342
							||(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1));
jehan's avatar
jehan committed
343

jehan's avatar
jehan committed
344

jehan's avatar
jehan committed
345 346
	if (linphone_core_get_calls_nb(callee_mgr->lc) == 1)
		BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc)); /*only relevant if one call, otherwise, not always set*/
347 348
	callee_call=linphone_core_get_call_by_remote_address2(callee_mgr->lc,caller_mgr->identity);

jehan's avatar
jehan committed
349
	if(!linphone_core_get_current_call(caller_mgr->lc) || (!callee_call && !linphone_core_get_current_call(callee_mgr->lc)) /*for privacy case*/) {
jehan's avatar
jehan committed
350
		return 0;
351
	} else if (caller_mgr->identity){
jehan's avatar
jehan committed
352 353
		LinphoneAddress* callee_from=linphone_address_clone(caller_mgr->identity);
		linphone_address_set_port(callee_from,0); /*remove port because port is never present in from header*/
354

jehan's avatar
jehan committed
355
		if (linphone_call_params_get_privacy(linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc))) == LinphonePrivacyNone) {
356 357
			/*don't check in case of p asserted id*/
			if (!lp_config_get_int(callee_mgr->lc->config,"sip","call_logs_use_asserted_id_instead_of_from",0))
358
				BC_ASSERT_TRUE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(callee_call)));
jehan's avatar
jehan committed
359
		} else {
360
			BC_ASSERT_FALSE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(linphone_core_get_current_call(callee_mgr->lc))));
jehan's avatar
jehan committed
361
		}
362
		linphone_address_unref(callee_from);
363
	}
364 365


366
	if (callee_params){
367
		linphone_call_accept_with_params(callee_call,callee_params);
368
	}else if (build_callee_params){
369
		LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,callee_call);
370
		ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params));
371
		linphone_call_accept_with_params(callee_call,default_params);
372
		linphone_call_params_unref(default_params);
373
	}else if (callee_call) {
374
		linphone_call_accept(callee_call);
375 376
	} else {
		linphone_call_accept(linphone_core_get_current_call(callee_mgr->lc));
377
	}
jehan's avatar
jehan committed
378

379
	BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1));
jehan's avatar
jehan committed
380
	BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1));
381

382
	result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000)
jehan's avatar
jehan committed
383
			&&
384
			wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000);
jehan's avatar
jehan committed
385

386
	if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone
jehan's avatar
jehan committed
387
		|| linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) {
johan's avatar
johan committed
388
		/*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/
jehan's avatar
jehan committed
389
		if (	(linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
390
				|| (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP) /* if callee is ZRTP, wait for it */
jehan's avatar
jehan committed
391
				|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS))
392
			wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_caller.number_of_LinphoneCallEncryptedOn+1);
jehan's avatar
jehan committed
393 394
		if ((linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
			|| (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionDTLS)
johan's avatar
johan committed
395
			|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
jehan's avatar
jehan committed
396
			|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS) /*also take care of caller policy*/ )
397
			wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1);
johan's avatar
johan committed
398 399

		/* when caller is encryptionNone but callee is ZRTP, we expect ZRTP to take place */
400 401
		if ((linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionNone)
			&& (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
402
			&& linphone_core_media_encryption_supported(caller_mgr->lc, LinphoneMediaEncryptionZRTP)) {
johan's avatar
johan committed
403 404 405 406 407
			const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param), LinphoneMediaEncryptionZRTP, int, "%d");
			call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc));
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param), LinphoneMediaEncryptionZRTP, int, "%d");
		}else { /* otherwise, final status shall stick to caller core parameter */
408
			const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
409
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc), int, "%d");
Simon Morlat's avatar
Simon Morlat committed
410
			call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc));
411
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc), int, "%d");
412

413
		}
jehan's avatar
jehan committed
414
	}
415 416 417
	/*wait ice re-invite*/
	if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce
			&& linphone_core_get_firewall_policy(callee_mgr->lc) == LinphonePolicyUseIce
418 419
			&& !linphone_core_sdp_200_ack_enabled(caller_mgr->lc) /*ice does not work with sdp less invite*/
			&& lp_config_get_int(callee_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE)
420 421
			&& lp_config_get_int(caller_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE)
			&& linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionDTLS /*no ice-reinvite with DTLS*/) {
422 423 424
		BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2));
		BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2));

425 426 427 428
	} else if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce) {
		/* check no ice re-invite received*/
		BC_ASSERT_FALSE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2,2000));
		BC_ASSERT_FALSE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2,2000));
429

Simon Morlat's avatar
Simon Morlat committed
430 431 432
	}else{
		/*wait a bit for streams to start flowing*/
		wait_for_until(callee_mgr->lc,caller_mgr->lc, NULL, 0, 500);
433 434 435 436 437 438 439 440
	}
	if (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS ) {
		if (linphone_core_get_current_call(caller_mgr->lc)->audiostream)
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&linphone_core_get_current_call(caller_mgr->lc)->audiostream->ms.sessions));
#ifdef VIDEO_ENABLED
		if (linphone_core_get_current_call(caller_mgr->lc)->videostream && video_stream_started(linphone_core_get_current_call(caller_mgr->lc)->videostream))
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&linphone_core_get_current_call(caller_mgr->lc)->videostream->ms.sessions));
#endif
441

442
	}
jehan's avatar
jehan committed
443
	return result;
jehan's avatar
jehan committed
444
}
445

446 447 448 449 450 451 452 453
/*
 * CAUTION this function is error prone. you should not use it anymore in new tests.
 * Creating callee call params before the call is actually received is not the good way
 * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing
 * the call object for which params are to be created.
 * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how
 * callee params will be set by linphone_core_create_call_params().
 * This function was developped at a time where the use of the API about incoming params was not yet clarified.
454
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
455 456
 * it is not a so good idea to build new tests based on this function.
**/
457 458
bool_t call_with_params(LinphoneCoreManager* caller_mgr
						,LinphoneCoreManager* callee_mgr
459 460 461 462
						,const LinphoneCallParams *caller_params
						,const LinphoneCallParams *callee_params){
	LinphoneCallTestParams caller_test_params = {0}, callee_test_params =  {0};
	caller_test_params.base = (LinphoneCallParams*)caller_params;
463
	callee_test_params.base = (LinphoneCallParams*)callee_params;
464 465 466
	return call_with_params2(caller_mgr,callee_mgr,&caller_test_params,&callee_test_params,FALSE);
}

467 468 469 470 471 472 473 474
/*
 * CAUTION this function is error prone. you should not use it anymore in new tests.
 * Creating callee call params before the call is actually received is not the good way
 * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing
 * the call object for which params are to be created.
 * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how
 * callee params will be set by linphone_core_create_call_params().
 * This function was developped at a time where the use of the API about incoming params was not yet clarified.
475
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
476 477
 * it is not a so good idea to build new tests based on this function.
**/
478 479 480 481 482
bool_t call_with_test_params(LinphoneCoreManager* caller_mgr
				,LinphoneCoreManager* callee_mgr
				,const LinphoneCallTestParams *caller_test_params
				,const LinphoneCallTestParams *callee_test_params){
	return call_with_params2(caller_mgr,callee_mgr,caller_test_params,callee_test_params,FALSE);
483 484
}

485 486 487
bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params) {
	return call_with_params(caller_mgr,callee_mgr,params,NULL);
}
488

Simon Morlat's avatar
Simon Morlat committed
489
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){
490
	return call_with_params(caller_mgr,callee_mgr,NULL,NULL);
Simon Morlat's avatar
Simon Morlat committed
491 492
}

493
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){
494 495
	int previous_count_1 = m1->stat.number_of_LinphoneCallEnd;
	int previous_count_2 = m2->stat.number_of_LinphoneCallEnd;
Simon Morlat's avatar
Simon Morlat committed
496
	linphone_core_terminate_all_calls(m1->lc);
497 498 499 500
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,previous_count_1+1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,previous_count_2+1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallReleased,previous_count_1+1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallReleased,previous_count_2+1));
Simon Morlat's avatar
Simon Morlat committed
501 502
}

jehan's avatar
jehan committed
503
void simple_call_base(bool_t enable_multicast_recv_side) {
504 505
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
506 507
	const LinphoneAddress *from;
	LinphoneCall *pauline_call;
508
	LinphoneProxyConfig* marie_cfg;
509

510
	marie = linphone_core_manager_new( "marie_rc");
511
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
512

513 514 515
	/* with the account manager, we might lose the identity */
	marie_cfg = linphone_core_get_default_proxy_config(marie->lc);
	{
516
		LinphoneAddress* marie_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(marie_cfg));
517 518 519
		char* marie_tmp_id = NULL;
		linphone_address_set_display_name(marie_addr, "Super Marie");
		marie_tmp_id = linphone_address_as_string(marie_addr);
520

521 522 523
		linphone_proxy_config_edit(marie_cfg);
		linphone_proxy_config_set_identity(marie_cfg,marie_tmp_id);
		linphone_proxy_config_done(marie_cfg);
524

525
		ms_free(marie_tmp_id);
526
		linphone_address_unref(marie_addr);
527
	}
528

529
	linphone_core_enable_audio_multicast(pauline->lc,enable_multicast_recv_side);
jehan's avatar
jehan committed
530

531 532 533 534 535 536 537 538 539 540 541 542
	BC_ASSERT_TRUE(call(marie,pauline));
	pauline_call=linphone_core_get_current_call(pauline->lc);
	BC_ASSERT_PTR_NOT_NULL(pauline_call);
	/*check that display name is correctly propagated in From */
	if (pauline_call){
		from=linphone_call_get_remote_address(linphone_core_get_current_call(pauline->lc));
		BC_ASSERT_PTR_NOT_NULL(from);
		if (from){
			const char *dname=linphone_address_get_display_name(from);
			BC_ASSERT_PTR_NOT_NULL(dname);
			if (dname){
				BC_ASSERT_STRING_EQUAL(dname, "Super Marie");
543 544
			}
		}
545
	}
546

547 548 549
	liblinphone_tester_check_rtcp(marie,pauline);
	end_call(marie,pauline);
	linphone_core_manager_destroy(pauline);
550
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
551
}
552

553
static void simple_call(void) {
jehan's avatar
jehan committed
554 555
	simple_call_base(FALSE);
}
556

557 558 559 560
/*This test is added to reproduce a crash when a call is failed synchronously*/
static void  simple_call_with_no_sip_transport(void){
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
561
	LinphoneSipTransports tr={0};
562 563 564 565 566 567 568 569 570 571 572 573 574 575
	LinphoneCall *call;

	marie = linphone_core_manager_new( "marie_rc");
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");

	/*disable all transports so that the call will fail synchronously*/
	linphone_core_set_sip_transports(marie->lc, &tr);

	call = linphone_core_invite_address(marie->lc, pauline->identity);
	BC_ASSERT_PTR_NULL(call);
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie);
}

576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
static void simple_call_with_udp(void) {
	LinphoneCoreManager* michelle;
	LinphoneCoreManager* laure;
	const LinphoneAddress *from;
	LinphoneCall *laure_call;
	LinphoneProxyConfig* michelle_cfg;

	michelle = linphone_core_manager_new( "michelle_rc_udp");
	laure = linphone_core_manager_new("laure_rc_udp");

	/* with the account manager, we might lose the identity */
	michelle_cfg = linphone_core_get_default_proxy_config(michelle->lc);
	{
		LinphoneAddress* michelle_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(michelle_cfg));
		char* michelle_tmp_id = NULL;
		linphone_address_set_display_name(michelle_addr, "Super michelle");
		michelle_tmp_id = linphone_address_as_string(michelle_addr);

		linphone_proxy_config_edit(michelle_cfg);
		linphone_proxy_config_set_identity(michelle_cfg,michelle_tmp_id);
		linphone_proxy_config_done(michelle_cfg);

		ms_free(michelle_tmp_id);
599
		linphone_address_unref(michelle_addr);
600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
	}

	BC_ASSERT_TRUE(call(michelle,laure));
	laure_call=linphone_core_get_current_call(laure->lc);
	BC_ASSERT_PTR_NOT_NULL(laure_call);
	/*check that display name is correctly propagated in From */
	if (laure_call){
		from=linphone_call_get_remote_address(linphone_core_get_current_call(laure->lc));
		BC_ASSERT_PTR_NOT_NULL(from);
		if (from){
			const char *dname=linphone_address_get_display_name(from);
			BC_ASSERT_PTR_NOT_NULL(dname);
			if (dname){
				BC_ASSERT_STRING_EQUAL(dname, "Super michelle");
			}
		}
	}

	liblinphone_tester_check_rtcp(michelle,laure);
	end_call(michelle,laure);
	linphone_core_manager_destroy(laure);
	linphone_core_manager_destroy(michelle);
}

624
static void automatic_call_termination(void) {
625 626 627 628 629 630 631 632 633 634
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;

	marie = linphone_core_manager_new( "marie_rc");
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");


	if (!BC_ASSERT_TRUE(call(marie,pauline))) goto end;

	liblinphone_tester_check_rtcp(marie,pauline);
635

636 637 638 639 640 641 642 643 644 645
	linphone_core_destroy(pauline->lc);
	pauline->lc = NULL;
	/*marie shall receive the BYE*/
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
	BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1));
end:
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie);
}

646
static void call_with_timed_out_bye(void) {
jehan's avatar
jehan committed
647 648 649 650 651
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
	belle_sip_timer_config_t timer_config;

	marie = linphone_core_manager_new( "marie_rc");
652
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
jehan's avatar
jehan committed
653

654
	BC_ASSERT_TRUE(call(marie,pauline));
jehan's avatar
jehan committed
655 656 657 658 659 660 661

	sal_set_send_error(pauline->lc->sal,1500); /*to trash the message without generating error*/
	timer_config.T1=50; /*to have timer F = 3s*/
	timer_config.T2=4000;
	timer_config.T3=0;
	timer_config.T4=5000;

662
	belle_sip_stack_set_timer_config(sal_get_stack_impl(pauline->lc->sal),&timer_config);
jehan's avatar
jehan committed
663 664
	linphone_core_terminate_all_calls(pauline->lc);

665 666
	BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallReleased,1,timer_config.T1*84));
jehan's avatar
jehan committed
667 668 669 670

	sal_set_send_error(pauline->lc->sal,0);

	linphone_core_terminate_all_calls(marie->lc);
671 672
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1,5000));
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallReleased,1,5000));
jehan's avatar
jehan committed
673 674 675 676 677

	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

678
static void direct_call_over_ipv6(void){
Simon Morlat's avatar
Simon Morlat committed
679 680 681 682
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;

	if (liblinphone_tester_ipv6_available()){
683
		LinphoneSipTransports pauline_transports;
684
		LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp");
Simon Morlat's avatar
Simon Morlat committed
685
		marie = linphone_core_manager_new( "marie_rc");
686
		pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
687

Simon Morlat's avatar
Simon Morlat committed
688 689 690
		linphone_core_enable_ipv6(marie->lc,TRUE);
		linphone_core_enable_ipv6(pauline->lc,TRUE);
		linphone_core_set_default_proxy_config(marie->lc,NULL);
691
		linphone_core_set_default_proxy_config(pauline->lc, NULL);
692

693 694 695
		linphone_core_get_sip_transports_used(pauline->lc,&pauline_transports);
		linphone_address_set_port(pauline_dest,pauline_transports.tcp_port);
		linphone_core_invite_address(marie->lc,pauline_dest);
696

697 698
		BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallOutgoingRinging,1));
		BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallIncomingReceived,1));
699
		linphone_call_accept(linphone_core_get_current_call(pauline->lc));
700 701
		BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1));
		BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1));
702

Simon Morlat's avatar
Simon Morlat committed
703 704 705 706
		liblinphone_tester_check_rtcp(marie,pauline);
		end_call(marie,pauline);
		linphone_core_manager_destroy(marie);
		linphone_core_manager_destroy(pauline);
707
		linphone_address_unref(pauline_dest);
Simon Morlat's avatar
Simon Morlat committed
708 709 710
	}else ms_warning("Test skipped, no ipv6 available");
}

711
static void call_outbound_with_multiple_proxy(void) {
712
	LinphoneCoreManager* marie   = linphone_core_manager_new2( "marie_rc", FALSE);
713
	LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_tcp_rc", FALSE);
714 715

	LinphoneProxyConfig* lpc = NULL;
Simon Morlat's avatar
Simon Morlat committed
716
	LinphoneProxyConfig* registered_lpc = linphone_core_create_proxy_config(marie->lc);
717

718
	lpc = linphone_core_get_default_proxy_config(marie->lc);
719 720
	linphone_core_set_default_proxy(marie->lc,NULL);

721
	if (!BC_ASSERT_PTR_NOT_NULL(lpc) || !BC_ASSERT_PTR_NOT_NULL(registered_lpc)) return;
722 723 724 725 726 727 728 729

	// create new LPC that will successfully register
	linphone_proxy_config_set_identity(registered_lpc, linphone_proxy_config_get_identity(lpc));
	linphone_proxy_config_set_server_addr(registered_lpc, linphone_proxy_config_get_addr(lpc));
	linphone_proxy_config_set_route(registered_lpc, linphone_proxy_config_get_route(lpc));
	linphone_proxy_config_enable_register(registered_lpc, TRUE);

	linphone_core_add_proxy_config(marie->lc, registered_lpc);
Simon Morlat's avatar
Simon Morlat committed
730
	linphone_proxy_config_unref(registered_lpc);
731 732 733

	// set first LPC to unreacheable proxy addr
	linphone_proxy_config_edit(lpc);
734 735
	linphone_proxy_config_set_server_addr(lpc,"sip:linphone.org:9016;transport=udp");
	linphone_proxy_config_set_route(lpc, "sip:linphone.org:9016;transport=udp;lr");
736 737
	linphone_proxy_config_done(lpc);

738
	BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 10000));
739

740
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200));
741
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 10000));
742 743

	// calling marie should go through the second proxy config
744
	BC_ASSERT_TRUE(call(marie, pauline));
Simon Morlat's avatar
Simon Morlat committed
745
	wait_for_until(marie->lc, pauline->lc, NULL, 0, 1000);
746

747
	end_call(marie, pauline);
748 749
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
750 751
}

752
#if 0 /* TODO: activate test when the implementation is ready */
753
static void multiple_answers_call(void) {
754
	/* Scenario is this: pauline calls marie, which is registered 2 times.
755
	   Both linphones answer at the same time, and only one should get the
756 757 758 759
	   call running, the other should be terminated */
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc" );
	LinphoneCoreManager* marie1  = linphone_core_manager_new( "marie_rc" );
	LinphoneCoreManager* marie2  = linphone_core_manager_new( "marie_rc" );
760

761
	LinphoneCall* call1, *call2;
762

763 764 765
	bctbx_list_t* lcs = bctbx_list_append(NULL,pauline->lc);
	lcs = bctbx_list_append(lcs,marie1->lc);
	lcs = bctbx_list_append(lcs,marie2->lc);
766 767


768
	BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000));
769

770
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
771

772 773 774
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 2000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 2000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress, 1, 2000));
775

776 777 778
	// marie 1 and 2 answer at the same time
	call1 = linphone_core_get_current_call(marie1->lc);
	call2 = linphone_core_get_current_call(marie2->lc);
779

780 781
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
782

783 784
	BC_ASSERT_EQUAL( linphone_core_accept_call(marie1->lc, call1), 0, int, "%d");
	BC_ASSERT_EQUAL( linphone_core_accept_call(marie2->lc, call2), 0, int, "%d");
785

786 787 788
	BC_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) );
	BC_ASSERT_TRUE( wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) );
	BC_ASSERT_TRUE( wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 2000) );
789 790


791 792 793
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
794 795 796
}
#endif

797
static void multiple_answers_call_with_media_relay(void) {
798

799
	/* Scenario is this: pauline calls marie, which is registered 2 times.
800
	 *   Both linphones answer at the same time, and only one should get the
801
	 *   call running, the other should be terminated */
802
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc" );
803 804
	LinphoneCoreManager* marie1  = linphone_core_manager_new( "marie_rc" );
	LinphoneCoreManager* marie2  = linphone_core_manager_new( "marie_rc" );
805

806
	LinphoneCall* call1, *call2;
807

808 809 810
	bctbx_list_t* lcs = bctbx_list_append(NULL,pauline->lc);
	lcs = bctbx_list_append(lcs,marie1->lc);
	lcs = bctbx_list_append(lcs,marie2->lc);
811

812 813 814
	linphone_core_set_user_agent(pauline->lc, "Natted Linphone", NULL);
	linphone_core_set_user_agent(marie1->lc, "Natted Linphone", NULL);
	linphone_core_set_user_agent(marie2->lc, "Natted Linphone", NULL);
815

816
	BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000));
817

818
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
819

820 821 822
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 2000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 2000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress, 1, 2000));
823

824 825 826
	// marie 1 and 2 answer at the same time
	call1 = linphone_core_get_current_call(marie1->lc);
	call2 = linphone_core_get_current_call(marie2->lc);
827

828
	if (BC_ASSERT_PTR_NOT_NULL(call1) && BC_ASSERT_PTR_NOT_NULL(call2)) {
829
		BC_ASSERT_EQUAL( linphone_call_accept(call1), 0, int, "%d");
830
		ms_sleep(1); /*sleep to make sure that the 200OK of marie1 reaches the server first*/
831
		BC_ASSERT_EQUAL( linphone_call_accept(call2), 0, int, "%d");
832

833 834 835 836
		BC_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) );
		BC_ASSERT_TRUE( wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) );
		/*the server will send a bye to marie2, as is 200Ok arrived second*/
		BC_ASSERT_TRUE( wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 4000) );
837

838 839
		end_call(marie1, pauline);
	}
840

841 842 843
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
844
	bctbx_list_free(lcs);
845 846
}

847
static void call_with_specified_codec_bitrate(void) {
848
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
849
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
850
	bool_t call_ok;
851
	const char * codec = "opus";
852
	int rate = 48000;
853
	int min_bw=24;
854
	int max_bw=50;
855

856
#ifdef __arm__
857
	if (ms_factory_get_cpu_count(marie->lc->factory) <2) { /*2 opus codec channel + resampler is too much for a single core*/
858
#ifndef __ANDROID__
859
		codec = "speex";
860 861 862
		rate = 8000;
		min_bw=20;
		max_bw=35;
863
#else
864
		BC_PASS("Test requires at least a dual core");
865 866
		goto end;
#endif
867 868
	}
#endif
869 870
	/*Force marie to play from file: if soundcard is used and it is silient, then vbr mode will drop down the bitrate
	 Note that a play file is already set by linphone_core_manager_new() (but not used)*/
871
	linphone_core_set_use_files(marie->lc, TRUE);
872 873

	if (linphone_core_find_payload_type(marie->lc,codec,rate,-1)==NULL){
874
		BC_PASS("opus codec not supported, test skipped.");
875 876
		goto end;
	}
877

878 879
	disable_all_audio_codecs_except_one(marie->lc,codec,rate);
	disable_all_audio_codecs_except_one(pauline->lc,codec,rate);
880

881
	linphone_core_set_payload_type_bitrate(marie->lc,
882
		linphone_core_find_payload_type(marie->lc,codec,rate,-1),
883
		max_bw);
884
	linphone_core_set_payload_type_bitrate(pauline->lc,
885
		linphone_core_find_payload_type(pauline->lc,codec,rate,-1),
886
		min_bw);
887

888
	BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
889 890
	if (!call_ok) goto end;
	liblinphone_tester_check_rtcp(marie,pauline);
891 892
	/*wait a bit that bitstreams are stabilized*/
	wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
893

894
	BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), (int)(min_bw+5+min_bw*.1), int, "%i");
895
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 10, int, "%i"); /*check that at least something is received */
896
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), (int)(max_bw-5-max_bw*.1), int, "%i");
897

898
	end_call(pauline, marie);
899 900 901 902 903
end:
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

904

905
void disable_all_codecs(const bctbx_list_t* elem, LinphoneCoreManager* call){
906

907
	PayloadType *pt;
908

909 910 911 912
	for(;elem!=NULL;elem=elem->next){
		pt=(PayloadType*)elem->data;
		linphone_core_enable_payload_type(call->lc,pt,FALSE);
	}
913 914 915 916 917 918
}
/***
 Disable all audio codecs , sends an INVITE with RTP port 0 and payload 0.
 Wait for SIP  488 unacceptable.
 ***/
static void call_with_no_audio_codec(void){
919

920 921 922
	LinphoneCoreManager* callee = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager* caller = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc");
	LinphoneCall* out_call ;
923

924
	const bctbx_list_t* elem =linphone_core_get_audio_codecs(caller->lc);
925

926
	disable_all_codecs(elem, caller);
927 928


929 930 931
	out_call = linphone_core_invite_address(caller->lc,callee->identity);
	linphone_call_ref(out_call);
	BC_ASSERT_TRUE(wait_for(caller->lc, callee->lc, &caller->stat.number_of_LinphoneCallOutgoingInit, 1));
932 933


934 935 936
	BC_ASSERT_TRUE(wait_for_until(caller->lc, callee->lc, &caller->stat.number_of_LinphoneCallError, 1, 6000));
	BC_ASSERT_EQUAL(linphone_call_get_reason(out_call), LinphoneReasonNotAcceptable, int, "%d");
	BC_ASSERT_EQUAL(callee->stat.number_of_LinphoneCallIncomingReceived, 0, int, "%d");
937

938 939 940
	linphone_call_unref(out_call);
	linphone_core_manager_destroy(callee);
	linphone_core_manager_destroy(caller);
941 942 943

}

944
static void simple_call_compatibility_mode(void) {
945
	char route[256];
946
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
947
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
948 949 950 951 952 953

	LinphoneCore* lc_marie=marie->lc;
	LinphoneCore* lc_pauline=pauline->lc;
	stats* stat_marie=&marie->stat;
	stats* stat_pauline=&pauline->stat;
	LinphoneProxyConfig* proxy;
954
	const LinphoneAddress* identity;
955 956
	LinphoneAddress* proxy_address;
	char*tmp;
957
	LinphoneSipTransports transport;
958

959
	proxy = linphone_core_get_default_proxy_config(lc_marie);
960
	BC_ASSERT_PTR_NOT_NULL (proxy);
961
	identity = linphone_proxy_config_get_identity_address(proxy);
962 963 964 965 966 967


	proxy_address=linphone_address_new(linphone_proxy_config_get_addr(proxy));
	linphone_address_clean(proxy_address);
	tmp=linphone_address_as_string_uri_only(proxy_address);
	linphone_proxy_config_set_server_addr(proxy,tmp);
968 969
	sprintf(route,"sip:%s",test_route);
	linphone_proxy_config_set_route(proxy,route);
970
	ms_free(tmp);
971
	linphone_address_unref(proxy_address);
972 973 974 975 976 977 978 979
	linphone_core_get_sip_transports(lc_marie,&transport);
	transport.udp_port=0;
	transport.tls_port=0;
	transport.dtls_port=0;
	/*only keep tcp*/
	linphone_core_set_sip_transports(lc_marie,&transport);
	stat_marie->number_of_LinphoneRegistrationOk=0;

980
	BC_ASSERT_TRUE (wait_for(lc_marie,lc_marie,&stat_marie->number_of_LinphoneRegistrationOk,1));
981

982
	linphone_core_invite_address(lc_marie,pauline->identity);
983

984 985 986 987
	BC_ASSERT_TRUE (wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallIncomingReceived,1));
	BC_ASSERT_TRUE(linphone_core_inc_invite_pending(lc_pauline));
	BC_ASSERT_EQUAL(stat_marie->number_of_LinphoneCallOutgoingProgress,1, int, "%d");
	BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallOutgoingRinging,1));
988

989
	BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(lc_pauline));
990
	if (linphone_core_get_current_call_remote_address(lc_pauline)) {
991
		BC_ASSERT_TRUE(linphone_address_weak_equal(identity,linphone_core_get_current_call_remote_address(lc_pauline)));
992

993
		linphone_call_accept(linphone_core_get_current_call(lc_pauline));
994

995 996 997 998
		BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallConnected,1));
		BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallConnected,1));
		BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_pauline->number_of_LinphoneCallStreamsRunning,1));
		BC_ASSERT_TRUE(wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,1));
999

1000
		wait_for(lc_pauline,lc_marie,&stat_marie->number_of_LinphoneCallStreamsRunning,3);
Simon Morlat's avatar
Simon Morlat committed
1001
		wait_for_until(lc_pauline,lc_marie,NULL,0, 1000);
1002
		end_call(pauline, marie);
1003 1004 1005 1006 1007
	}
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

1008
static void terminate_call_with_error(void) {
Sandrine Avakian's avatar
Sandrine Avakian committed
1009 1010
	LinphoneCall* call_callee ;
	LinphoneErrorInfo *ei  ;
1011
	const LinphoneErrorInfo *rei = NULL;
1012 1013
	LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");