call_single_tester.c 296 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
#include "liblinphone_tester.h"
Benjamin REIS's avatar
Benjamin REIS committed
25
#include "tester_utils.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
void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){
48 49 50
	LinphoneCallLog *calllog = linphone_call_get_call_log(call);
	char* to=linphone_address_as_string(linphone_call_log_get_to(calllog));
	char* from=linphone_address_as_string(linphone_call_log_get_from(calllog));
51
	stats* counters;
52
	ms_message(" %s call from [%s] to [%s], new state is [%s]"	,linphone_call_log_get_dir(calllog)==LinphoneCallIncoming?"Incoming":"Outgoing"
jehan's avatar
jehan committed
53 54 55
																,from
																,to
																,linphone_call_state_to_string(cstate));
jehan's avatar
jehan committed
56 57
	ms_free(to);
	ms_free(from);
58
	counters = get_stats(lc);
jehan's avatar
jehan committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
	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;
78 79
	case LinphoneCallEarlyUpdating: counters->number_of_LinphoneCallEarlyUpdating++;break;
	case LinphoneCallEarlyUpdatedByRemote: counters->number_of_LinphoneCallEarlyUpdatedByRemote++;break;
jehan's avatar
jehan committed
80
	default:
81
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
82 83
	}
}
84

85 86 87 88 89 90 91 92 93
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) {
94
				counters->number_of_tmmbr_received++;
95 96 97 98 99 100 101
				counters->last_tmmbr_value_received = (int)rtcp_RTPFB_tmmbr_get_max_bitrate(packet);
			}
		}
	}while (rtcp_next_packet(packet));
	rtcp_rewind(packet);
}

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

132 133
}

134
void linphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) {
135 136 137
	LinphoneCallLog *calllog = linphone_call_get_call_log(call);
	char* to=linphone_address_as_string(linphone_call_log_get_to(calllog));
	char* from=linphone_address_as_string(linphone_call_log_get_from(calllog));
138
	stats* counters;
139
	ms_message(" %s call from [%s] to [%s], is now [%s]",linphone_call_log_get_dir(calllog)==LinphoneCallIncoming?"Incoming":"Outgoing"
140 141 142 143 144 145 146 147 148 149 150
														,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
151

jehan's avatar
jehan committed
152
void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) {
153 154 155
	LinphoneCallLog *clog = linphone_call_get_call_log(transfered);
	char* to=linphone_address_as_string(linphone_call_log_get_to(clog));
	char* from=linphone_address_as_string(linphone_call_log_get_to(clog));
156
	stats* counters;
jehan's avatar
jehan committed
157 158 159 160
	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);

161
	counters = get_stats(lc);
jehan's avatar
jehan committed
162
	switch (new_call_state) {
jehan's avatar
jehan committed
163
	case LinphoneCallOutgoingInit :counters->number_of_LinphoneTransferCallOutgoingInit++;break;
164 165 166 167 168
	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;
169
	case LinphoneCallError :counters->number_of_LinphoneTransferCallError++;break;
jehan's avatar
jehan committed
170
	default:
171
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
172 173
	}
}
174

jehan's avatar
jehan committed
175

Simon Morlat's avatar
Simon Morlat committed
176
void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) {
177 178 179
	LinphoneCallLog *calllog = linphone_call_get_call_log(call);
	char* to=linphone_address_as_string(linphone_call_log_get_to(calllog));
	char* from=linphone_address_as_string(linphone_call_log_get_from(calllog));
180
	stats* counters;
jehan's avatar
jehan committed
181 182 183 184
	LinphoneCore* lc=(LinphoneCore*)user_data;
	ms_message("call from [%s] to [%s] receive iFrame",from,to);
	ms_free(to);
	ms_free(from);
185
	counters = (stats*)get_stats(lc);
jehan's avatar
jehan committed
186 187
	counters->number_of_IframeDecoded++;
}
Simon Morlat's avatar
Simon Morlat committed
188

189 190 191 192
#define reset_call_stats(var, value) \
	if (var) linphone_call_stats_unref(var); \
	var = value

Simon Morlat's avatar
Simon Morlat committed
193
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) {
194
	LinphoneCall *c1,*c2;
Simon Morlat's avatar
Simon Morlat committed
195
	MSTimeSpec ts;
jehan's avatar
jehan committed
196
	int max_time_to_wait;
197
	LinphoneCallStats *audio_stats1 = NULL, *video_stats1 = NULL, *audio_stats2 = NULL, *video_stats2 = NULL;
198 199
	c1=linphone_core_get_current_call(caller->lc);
	c2=linphone_core_get_current_call(callee->lc);
200

201 202
	BC_ASSERT_PTR_NOT_NULL(c1);
	BC_ASSERT_PTR_NOT_NULL(c2);
203

Simon Morlat's avatar
Simon Morlat committed
204
	if (!c1 || !c2) return;
jehan's avatar
jehan committed
205 206
	linphone_call_ref(c1);
	linphone_call_ref(c2);
Simon Morlat's avatar
Simon Morlat committed
207
	liblinphone_tester_clock_start(&ts);
jehan's avatar
jehan committed
208 209 210 211
	if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc))
		max_time_to_wait = 15000;
	else
		max_time_to_wait = 5000;
212

Simon Morlat's avatar
Simon Morlat committed
213
	do {
214 215 216 217
		reset_call_stats(audio_stats1, linphone_call_get_audio_stats(c1));
		reset_call_stats(video_stats1, linphone_call_get_video_stats(c1));
		reset_call_stats(audio_stats2, linphone_call_get_audio_stats(c2));
		reset_call_stats(video_stats2, linphone_call_get_video_stats(c2));
218 219 220 221
		if (linphone_call_stats_get_round_trip_delay(audio_stats1) > 0.0
			&& linphone_call_stats_get_round_trip_delay(audio_stats2) > 0.0
			&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || linphone_call_stats_get_round_trip_delay(video_stats1)>0.0)
			&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2))  || linphone_call_stats_get_round_trip_delay(video_stats2)>0.0)) {
222
			break;
223

224
		}
225
		wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/
jehan's avatar
jehan committed
226
	}while (!liblinphone_tester_clock_elapsed(&ts,max_time_to_wait));
Benjamin REIS's avatar
Benjamin REIS committed
227

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

265
	}
Benjamin REIS's avatar
Benjamin REIS committed
266

267 268 269 270
	if (audio_stats1) linphone_call_stats_unref(audio_stats1);
	if (audio_stats2) linphone_call_stats_unref(audio_stats2);
	if (video_stats1) linphone_call_stats_unref(video_stats1);
	if (video_stats2) linphone_call_stats_unref(video_stats2);
Benjamin REIS's avatar
Benjamin REIS committed
271

jehan's avatar
jehan committed
272 273
	linphone_call_unref(c1);
	linphone_call_unref(c2);
274 275
}

276 277
static void setup_sdp_handling(const LinphoneCallTestParams* params, LinphoneCoreManager* mgr ){
	if( params->sdp_removal ){
278
		sal_default_set_sdp_handling(linphone_core_get_sal(mgr->lc), SalOpSDPSimulateRemove);
279
	} else if( params->sdp_simulate_error ){
280
		sal_default_set_sdp_handling(linphone_core_get_sal(mgr->lc), SalOpSDPSimulateError);
281 282 283
	}
}

284 285 286 287 288 289 290 291
/*
 * 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.
292
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
293 294
 * it is not a so good idea to build new tests based on this function.
**/
295
bool_t call_with_params2(LinphoneCoreManager* caller_mgr
296
						,LinphoneCoreManager* callee_mgr
297 298 299
						, const LinphoneCallTestParams *caller_test_params
						, const LinphoneCallTestParams *callee_test_params
						, bool_t build_callee_params) {
jehan's avatar
jehan committed
300
	int retry=0;
jehan's avatar
jehan committed
301 302
	stats initial_caller=caller_mgr->stat;
	stats initial_callee=callee_mgr->stat;
jehan's avatar
jehan committed
303
	bool_t result=FALSE;
304 305
	LinphoneCallParams *caller_params = caller_test_params->base;
	LinphoneCallParams *callee_params = callee_test_params->base;
306
	bool_t did_receive_call;
307
	LinphoneCall *callee_call=NULL;
308
	LinphoneCall *caller_call=NULL;
309

310 311 312 313
	/* 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);

314 315
	setup_sdp_handling(caller_test_params, caller_mgr);
	setup_sdp_handling(callee_test_params, callee_mgr);
316

317
	if (!caller_params){
318
		BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity)));
Simon Morlat's avatar
Simon Morlat committed
319
	}else{
320
		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
321
	}
322

323
	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
324

325
	did_receive_call = wait_for(callee_mgr->lc
326 327 328
				,caller_mgr->lc
				,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
				,initial_callee.number_of_LinphoneCallIncomingReceived+1);
329
	BC_ASSERT_EQUAL(did_receive_call, !callee_test_params->sdp_simulate_error, int, "%d");
330

331 332
	sal_default_set_sdp_handling(linphone_core_get_sal(caller_mgr->lc), SalOpSDPNormal);
	sal_default_set_sdp_handling(linphone_core_get_sal(caller_mgr->lc), SalOpSDPNormal);
333

334
	if (!did_receive_call) return 0;
335 336


337
	if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
338
		BC_ASSERT_TRUE(linphone_core_is_incoming_invite_pending(callee_mgr->lc));
339
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d");
jehan's avatar
jehan committed
340

jehan's avatar
jehan committed
341

jehan's avatar
jehan committed
342 343
	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)
344
			&& retry++ < 100) {
jehan's avatar
jehan committed
345 346
			linphone_core_iterate(caller_mgr->lc);
			linphone_core_iterate(callee_mgr->lc);
347
			ms_usleep(20000);
jehan's avatar
jehan committed
348 349 350
	}


351
	BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1)
Simon Morlat's avatar
Simon Morlat committed
352
							||(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1));
jehan's avatar
jehan committed
353

jehan's avatar
jehan committed
354

jehan's avatar
jehan committed
355 356
	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*/
357 358
	callee_call=linphone_core_get_call_by_remote_address2(callee_mgr->lc,caller_mgr->identity);

jehan's avatar
jehan committed
359
	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
360
		return 0;
361
	} else if (caller_mgr->identity){
jehan's avatar
jehan committed
362 363
		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*/
364

jehan's avatar
jehan committed
365
		if (linphone_call_params_get_privacy(linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc))) == LinphonePrivacyNone) {
366
			/*don't check in case of p asserted id*/
367
			if (!lp_config_get_int(linphone_core_get_config(callee_mgr->lc),"sip","call_logs_use_asserted_id_instead_of_from",0))
368
				BC_ASSERT_TRUE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(callee_call)));
jehan's avatar
jehan committed
369
		} else {
370
			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
371
		}
372
		linphone_address_unref(callee_from);
373
	}
374 375


376
	if (callee_params){
377
		linphone_call_accept_with_params(callee_call,callee_params);
378
	}else if (build_callee_params){
379
		LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,callee_call);
380
		ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params));
381
		linphone_call_accept_with_params(callee_call,default_params);
382
		linphone_call_params_unref(default_params);
383
	}else if (callee_call) {
384
		linphone_call_accept(callee_call);
385 386
	} else {
		linphone_call_accept(linphone_core_get_current_call(callee_mgr->lc));
387
	}
jehan's avatar
jehan committed
388

389
	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
390
	BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1));
391

392
	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
393
			&&
394
			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
395

396
	if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone
jehan's avatar
jehan committed
397
		|| linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) {
johan's avatar
johan committed
398
		/*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/
jehan's avatar
jehan committed
399
		if (	(linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
400
				|| (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP) /* if callee is ZRTP, wait for it */
jehan's avatar
jehan committed
401
				|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS))
402
			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
403 404
		if ((linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
			|| (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionDTLS)
johan's avatar
johan committed
405
			|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
jehan's avatar
jehan committed
406
			|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS) /*also take care of caller policy*/ )
407
			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
408 409

		/* when caller is encryptionNone but callee is ZRTP, we expect ZRTP to take place */
410 411
		if ((linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionNone)
			&& (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
412
			&& linphone_core_media_encryption_supported(caller_mgr->lc, LinphoneMediaEncryptionZRTP)) {
johan's avatar
johan committed
413 414 415 416 417
			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 */
418
			const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
419
			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
420
			call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc));
421
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc), int, "%d");
422

423
		}
jehan's avatar
jehan committed
424
	}
425 426 427
	/*wait ice re-invite*/
	if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce
			&& linphone_core_get_firewall_policy(callee_mgr->lc) == LinphonePolicyUseIce
428
			&& !linphone_core_sdp_200_ack_enabled(caller_mgr->lc) /*ice does not work with sdp less invite*/
429 430
			&& lp_config_get_int(linphone_core_get_config(callee_mgr->lc), "sip", "update_call_when_ice_completed", TRUE)
			&& lp_config_get_int(linphone_core_get_config(callee_mgr->lc), "sip", "update_call_when_ice_completed", TRUE)
431
			&& linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionDTLS /*no ice-reinvite with DTLS*/) {
432 433 434
		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));

435 436 437 438
	} 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));
439

440 441
	}
	if (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS ) {
442 443 444 445 446 447 448
		LinphoneCall *call = linphone_core_get_current_call(caller_mgr->lc);
		AudioStream *astream = (AudioStream *)linphone_call_get_stream(call, LinphoneStreamTypeAudio);
#ifdef VIDEO_ENABLED
		VideoStream *vstream = (VideoStream *)linphone_call_get_stream(call, LinphoneStreamTypeVideo);
#endif
		if (astream)
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&astream->ms.sessions));
449
#ifdef VIDEO_ENABLED
450 451
		if (vstream && video_stream_started(vstream))
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&vstream->ms.sessions));
452
#endif
453

454
	}
jehan's avatar
jehan committed
455
	return result;
jehan's avatar
jehan committed
456
}
457

458 459 460 461 462 463 464 465
/*
 * 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.
466
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
467 468
 * it is not a so good idea to build new tests based on this function.
**/
469 470
bool_t call_with_params(LinphoneCoreManager* caller_mgr
						,LinphoneCoreManager* callee_mgr
471 472 473 474
						,const LinphoneCallParams *caller_params
						,const LinphoneCallParams *callee_params){
	LinphoneCallTestParams caller_test_params = {0}, callee_test_params =  {0};
	caller_test_params.base = (LinphoneCallParams*)caller_params;
475
	callee_test_params.base = (LinphoneCallParams*)callee_params;
476 477 478
	return call_with_params2(caller_mgr,callee_mgr,&caller_test_params,&callee_test_params,FALSE);
}

479 480 481 482 483 484 485 486
/*
 * 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.
487
 * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so
488 489
 * it is not a so good idea to build new tests based on this function.
**/
490 491 492 493 494
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);
495 496
}

497 498 499
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);
}
500

Simon Morlat's avatar
Simon Morlat committed
501
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){
502
	return call_with_params(caller_mgr,callee_mgr,NULL,NULL);
Simon Morlat's avatar
Simon Morlat committed
503 504
}

505
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){
506 507
	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
508
	linphone_core_terminate_all_calls(m1->lc);
509 510 511 512
	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
513 514
}

jehan's avatar
jehan committed
515
void simple_call_base(bool_t enable_multicast_recv_side) {
516 517
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
518 519
	const LinphoneAddress *from;
	LinphoneCall *pauline_call;
520
	LinphoneProxyConfig* marie_cfg;
521

522
	marie = linphone_core_manager_new( "marie_rc");
523
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
524

525 526 527
	/* with the account manager, we might lose the identity */
	marie_cfg = linphone_core_get_default_proxy_config(marie->lc);
	{
528
		LinphoneAddress* marie_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(marie_cfg));
529 530 531
		char* marie_tmp_id = NULL;
		linphone_address_set_display_name(marie_addr, "Super Marie");
		marie_tmp_id = linphone_address_as_string(marie_addr);
532

533 534 535
		linphone_proxy_config_edit(marie_cfg);
		linphone_proxy_config_set_identity(marie_cfg,marie_tmp_id);
		linphone_proxy_config_done(marie_cfg);
536

537
		ms_free(marie_tmp_id);
538
		linphone_address_unref(marie_addr);
539
	}
540

541
	linphone_core_enable_audio_multicast(pauline->lc,enable_multicast_recv_side);
jehan's avatar
jehan committed
542

543 544 545 546 547 548 549 550 551 552 553 554
	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");
555 556
			}
		}
557
	}
558

559 560 561
	liblinphone_tester_check_rtcp(marie,pauline);
	end_call(marie,pauline);
	linphone_core_manager_destroy(pauline);
562
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
563
}
564

565
static void simple_call(void) {
jehan's avatar
jehan committed
566 567
	simple_call_base(FALSE);
}
568

569 570 571 572
/*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;
573
	LinphoneSipTransports tr={0};
574 575 576 577 578 579 580 581 582 583 584 585 586 587
	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);
}

588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610
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);
611
		linphone_address_unref(michelle_addr);
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
	}

	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);
}

636
static void automatic_call_termination(void) {
637 638 639 640 641 642 643 644 645 646
	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);
647

648 649 650 651 652 653 654 655 656 657
	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);
}

658
static void call_with_timed_out_bye(void) {
jehan's avatar
jehan committed
659 660 661 662 663
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
	belle_sip_timer_config_t timer_config;

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

666
	BC_ASSERT_TRUE(call(marie,pauline));
jehan's avatar
jehan committed
667

668
	sal_set_send_error(linphone_core_get_sal(pauline->lc),1500); /*to trash the message without generating error*/
jehan's avatar
jehan committed
669 670 671 672 673
	timer_config.T1=50; /*to have timer F = 3s*/
	timer_config.T2=4000;
	timer_config.T3=0;
	timer_config.T4=5000;

674
	belle_sip_stack_set_timer_config(sal_get_stack_impl(linphone_core_get_sal(pauline->lc)),&timer_config);
jehan's avatar
jehan committed
675 676
	linphone_core_terminate_all_calls(pauline->lc);

677 678
	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
679

680
	sal_set_send_error(linphone_core_get_sal(pauline->lc),0);
jehan's avatar
jehan committed
681 682

	linphone_core_terminate_all_calls(marie->lc);
683 684
	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
685 686 687 688 689

	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

690
static void direct_call_over_ipv6(void){
Simon Morlat's avatar
Simon Morlat committed
691 692 693 694
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;

	if (liblinphone_tester_ipv6_available()){
695
		LinphoneSipTransports pauline_transports;
696
		LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp");
Simon Morlat's avatar
Simon Morlat committed
697
		marie = linphone_core_manager_new( "marie_rc");
698
		pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
699

Simon Morlat's avatar
Simon Morlat committed
700 701 702
		linphone_core_enable_ipv6(marie->lc,TRUE);
		linphone_core_enable_ipv6(pauline->lc,TRUE);
		linphone_core_set_default_proxy_config(marie->lc,NULL);
703
		linphone_core_set_default_proxy_config(pauline->lc, NULL);
704

705 706 707
		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);
708

709 710
		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));
711
		linphone_call_accept(linphone_core_get_current_call(pauline->lc));
712 713
		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));
714

Simon Morlat's avatar
Simon Morlat committed
715 716 717 718
		liblinphone_tester_check_rtcp(marie,pauline);
		end_call(marie,pauline);
		linphone_core_manager_destroy(marie);
		linphone_core_manager_destroy(pauline);
719
		linphone_address_unref(pauline_dest);
Simon Morlat's avatar
Simon Morlat committed
720 721 722
	}else ms_warning("Test skipped, no ipv6 available");
}

723
static void call_outbound_with_multiple_proxy(void) {
724
	LinphoneCoreManager* marie   = linphone_core_manager_new2( "marie_rc", FALSE);
725
	LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_tcp_rc", FALSE);
726 727

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

730
	lpc = linphone_core_get_default_proxy_config(marie->lc);
731 732
	linphone_core_set_default_proxy(marie->lc,NULL);

733
	if (!BC_ASSERT_PTR_NOT_NULL(lpc) || !BC_ASSERT_PTR_NOT_NULL(registered_lpc)) return;
734 735 736 737 738 739 740 741

	// 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
742
	linphone_proxy_config_unref(registered_lpc);
743 744 745

	// set first LPC to unreacheable proxy addr
	linphone_proxy_config_edit(lpc);
746 747
	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");
748 749
	linphone_proxy_config_done(lpc);

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

752
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200));
753
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 10000));
754 755

	// calling marie should go through the second proxy config
756
	BC_ASSERT_TRUE(call(marie, pauline));
757

758
	end_call(marie, pauline);
759 760
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
761 762
}

763
#if 0 /* TODO: activate test when the implementation is ready */
764
static void multiple_answers_call(void) {
765
	/* Scenario is this: pauline calls marie, which is registered 2 times.
766
	   Both linphones answer at the same time, and only one should get the
767 768 769 770
	   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" );
771

772
	LinphoneCall* call1, *call2;
773

774 775 776
	bctbx_list_t* lcs = bctbx_list_append(NULL,pauline->lc);
	lcs = bctbx_list_append(lcs,marie1->lc);
	lcs = bctbx_list_append(lcs,marie2->lc);
777 778


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

781
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
782

783 784 785
	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));
786

787 788 789
	// 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);
790

791 792
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
793

794 795
	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");
796

797 798 799
	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) );
800 801


802 803 804
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
805 806 807
}
#endif

808
static void multiple_answers_call_with_media_relay(void) {
809

810
	/* Scenario is this: pauline calls marie, which is registered 2 times.
811
	 *   Both linphones answer at the same time, and only one should get the
812
	 *   call running, the other should be terminated */
813
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc" );
814 815
	LinphoneCoreManager* marie1  = linphone_core_manager_new( "marie_rc" );
	LinphoneCoreManager* marie2  = linphone_core_manager_new( "marie_rc" );
816

817
	LinphoneCall* call1, *call2;
818

819 820 821
	bctbx_list_t* lcs = bctbx_list_append(NULL,pauline->lc);
	lcs = bctbx_list_append(lcs,marie1->lc);
	lcs = bctbx_list_append(lcs,marie2->lc);
822

823 824 825
	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);
826

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

829
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
830

831 832 833
	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));
834

835 836 837
	// 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);
838

839
	if (BC_ASSERT_PTR_NOT_NULL(call1) && BC_ASSERT_PTR_NOT_NULL(call2)) {
840
		BC_ASSERT_EQUAL( linphone_call_accept(call1), 0, int, "%d");
841
		ms_sleep(1); /*sleep to make sure that the 200OK of marie1 reaches the server first*/
842
		BC_ASSERT_EQUAL( linphone_call_accept(call2), 0, int, "%d");
843

844 845 846 847
		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) );
848

849 850
		end_call(marie1, pauline);
	}
851

852 853 854
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
855
	bctbx_list_free(lcs);
856 857
}

858
static void call_with_specified_codec_bitrate(void) {
859
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
860
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
861
	bool_t call_ok;
862
	const char * codec = "opus";
863
	int rate = 48000;
864
	int min_bw=24;
865
	int max_bw=50;
866

867
#ifdef __arm__
868
	if (ms_factory_get_cpu_count(linphone_core_get_ms_factory(marie->lc)) <2) { /*2 opus codec channel + resampler is too much for a single core*/
869
#ifndef __ANDROID__
870
		codec = "speex";
871 872 873
		rate = 8000;
		min_bw=20;
		max_bw=35;
874
#else
875
		BC_PASS("Test requires at least a dual core");
876 877
		goto end;
#endif
878 879
	}
#endif
880 881
	/*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)*/
882
	linphone_core_set_use_files(marie->lc, TRUE);
883 884

	if (linphone_core_find_payload_type(marie->lc,codec,rate,-1)==NULL){
885
		BC_PASS("opus codec not supported, test skipped.");
886 887
		goto end;
	}
888

889 890
	disable_all_audio_codecs_except_one(marie->lc,codec,rate);
	disable_all_audio_codecs_except_one(pauline->lc,codec,rate);
891

892
	linphone_core_set_payload_type_bitrate(marie->lc,
893
		linphone_core_find_payload_type(marie->lc,codec,rate,-1),
894
		max_bw);
895
	linphone_core_set_payload_type_bitrate(pauline->lc,
896
		linphone_core_find_payload_type(pauline->lc,codec,rate,-1),
897
		min_bw);
898

899
	BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
900 901
	if (!call_ok) goto end;
	liblinphone_tester_check_rtcp(marie,pauline);
902 903
	/*wait a bit that bitstreams are stabilized*/
	wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
904

905
	BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), (int)(min_bw+5+min_bw*.1), int, "%i");
906
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 10, int, "%i"); /*check that at least something is received */
907
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), (int)(max_bw-5-max_bw*.1), int, "%i");
908

909
	end_call(pauline, marie);
910 911 912 913 914
end:
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

915

916
void disable_all_codecs(const bctbx_list_t* elem, LinphoneCoreManager* call){
917

918
	PayloadType *pt;
919

920 921 922 923
	for(;elem!=NULL;elem=elem->next){
		pt=(PayloadType*)elem->data;
		linphone_core_enable_payload_type(call->lc,pt,FALSE);
	}
924 925 926 927 928 929
}
/***
 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){
930

931 932 933
	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 ;
934

935
	const bctbx_list_t* elem =linphone_core_get_audio_codecs(caller->lc);
936

937
	disable_all_codecs(elem, caller);
938 939


940 941 942
	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));
943 944


945 946 947
	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");
948

949 950 951
	linphone_call_unref(out_call);
	linphone_core_manager_destroy(callee);
	linphone_core_manager_destroy(caller);
952 953 954

}

955
static void simple_call_compatibility_mode(void) {
956
	char route[256];
957
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
958
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
959 960 961 962 963 964

	LinphoneCore* lc_marie=marie->lc;
	LinphoneCore* lc_pauline=pauline->lc;
	stats* stat_marie=&marie->stat;
	stats* stat_pauline=&pauline->stat;
	LinphoneProxyConfig* proxy;
965
	const LinphoneAddress* identity;
966 967
	LinphoneAddress* proxy_address;
	char*tmp;
968
	LinphoneSipTransports transport;
969

970
	proxy = linphone_core_get_default_proxy_config(lc_marie);
971
	BC_ASSERT_PTR_NOT_NULL (proxy);
972
	identity = linphone_proxy_config_get_identity_address(proxy);
973 974 975 976 977 978


	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);
979 980
	sprintf(route,"sip:%s",test_route);
	linphone_proxy_config_set_route(proxy,route);
981
	ms_free(tmp);
982
	linphone_address_unref(proxy_address);
983 984 985 986 987 988 989 990
	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;

991
	BC_ASSERT_TRUE (wait_for(lc_marie,lc_marie,&stat_marie->number_of_LinphoneRegistrationOk,1));
992