call_tester.c 203 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
*/
Ghislain MARY's avatar
Ghislain MARY committed
18

Simon Morlat's avatar
Simon Morlat committed
19

Ghislain MARY's avatar
Ghislain MARY committed
20
#include <sys/types.h>
21
#include <sys/stat.h>
jehan's avatar
jehan committed
22
#include "linphonecore.h"
23
#include "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"
Simon Morlat's avatar
Simon Morlat committed
28

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

36 37 38 39 40 41 42 43 44 45
int static min(int a, int b) {
	if (a < b) return a;
	return b;
}

int static max(int a, int b) {
	if (a < b) return b;
	return a;
}

46
static void srtp_call(void);
Simon Morlat's avatar
Simon Morlat committed
47
static char *create_filepath(const char *dir, const char *filename, const char *ext);
jehan's avatar
jehan committed
48

49 50 51 52 53 54 55
// prototype definition for call_recording()
#ifdef ANDROID
#ifdef HAVE_OPENH264
extern void libmsopenh264_init(void);
#endif
#endif

jehan's avatar
jehan committed
56 57 58
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);
59
	stats* counters;
jehan's avatar
jehan committed
60 61 62 63
	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
64 65
	ms_free(to);
	ms_free(from);
66
	counters = get_stats(lc);
jehan's avatar
jehan committed
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
	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;
86 87
	case LinphoneCallEarlyUpdating: counters->number_of_LinphoneCallEarlyUpdating++;break;
	case LinphoneCallEarlyUpdatedByRemote: counters->number_of_LinphoneCallEarlyUpdatedByRemote++;break;
jehan's avatar
jehan committed
88
	default:
89
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
90 91
	}
}
92 93 94

void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) {
	stats* counters = get_stats(lc);
95
	counters->number_of_LinphoneCallStatsUpdated++;
96
	if (lstats->updated & LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) {
97
		counters->number_of_rtcp_received++;
98 99
	}
	if (lstats->updated & LINPHONE_CALL_STATS_SENT_RTCP_UPDATE ) {
100 101
		counters->number_of_rtcp_sent++;
	}
102 103 104 105 106 107 108 109 110 111 112 113
	if (lstats->updated & LINPHONE_CALL_STATS_PERIODICAL_UPDATE ) {
		int tab_size = sizeof (counters->audio_download_bandwidth)/sizeof(int);
		int index =  (counters->current_bandwidth_index++) % tab_size;

		counters->current_audio_download_bandwidth = counters->audio_download_bandwidth + index;
		counters->current_audio_upload_bandwidth = counters->audio_upload_bandwidth +index;

		counters->audio_download_bandwidth[index] = linphone_call_get_audio_stats(call)->download_bandwidth;
		counters->audio_upload_bandwidth[index] = linphone_call_get_audio_stats(call)->upload_bandwidth;
		counters->video_download_bandwidth[index] = linphone_call_get_video_stats(call)->download_bandwidth;
		counters->video_upload_bandwidth[index] = linphone_call_get_video_stats(call)->upload_bandwidth;
	}
114

115 116
}

jehan's avatar
jehan committed
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
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
133

jehan's avatar
jehan committed
134 135 136
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);
137
	stats* counters;
jehan's avatar
jehan committed
138 139 140 141
	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);

142
	counters = get_stats(lc);
jehan's avatar
jehan committed
143
	switch (new_call_state) {
jehan's avatar
jehan committed
144
	case LinphoneCallOutgoingInit :counters->number_of_LinphoneTransferCallOutgoingInit++;break;
145 146 147 148 149
	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;
150
	case LinphoneCallError :counters->number_of_LinphoneTransferCallError++;break;
jehan's avatar
jehan committed
151
	default:
152
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
153 154
	}
}
Ghislain MARY's avatar
Ghislain MARY committed
155

jehan's avatar
jehan committed
156 157

void linphone_call_cb(LinphoneCall *call,void * user_data) {
jehan's avatar
jehan committed
158 159
	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);
160
	stats* counters;
jehan's avatar
jehan committed
161 162 163 164
	LinphoneCore* lc=(LinphoneCore*)user_data;
	ms_message("call from [%s] to [%s] receive iFrame",from,to);
	ms_free(to);
	ms_free(from);
165
	counters = (stats*)get_stats(lc);
jehan's avatar
jehan committed
166 167
	counters->number_of_IframeDecoded++;
}
Simon Morlat's avatar
Simon Morlat committed
168

Simon Morlat's avatar
Simon Morlat committed
169
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) {
170
	LinphoneCall *c1,*c2;
Simon Morlat's avatar
Simon Morlat committed
171
	MSTimeSpec ts;
172 173 174

	c1=linphone_core_get_current_call(caller->lc);
	c2=linphone_core_get_current_call(callee->lc);
175

176 177
	BC_ASSERT_PTR_NOT_NULL(c1);
	BC_ASSERT_PTR_NOT_NULL(c2);
178

Simon Morlat's avatar
Simon Morlat committed
179
	if (!c1 || !c2) return;
jehan's avatar
jehan committed
180 181
	linphone_call_ref(c1);
	linphone_call_ref(c2);
182

Simon Morlat's avatar
Simon Morlat committed
183 184
	liblinphone_tester_clock_start(&ts);
	do {
185 186
		if (linphone_call_get_audio_stats(c1)->round_trip_delay > 0.0
				&& linphone_call_get_audio_stats(c2)->round_trip_delay > 0.0
jehan's avatar
jehan committed
187 188
				&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || linphone_call_get_video_stats(c1)->round_trip_delay>0.0)
				&& (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2))  || linphone_call_get_video_stats(c2)->round_trip_delay>0.0)) {
189
			break;
jehan's avatar
jehan committed
190

191
		}
192 193
		wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/
	}while (!liblinphone_tester_clock_elapsed(&ts,15000));
194 195
	BC_ASSERT_GREATER(linphone_call_get_audio_stats(c1)->round_trip_delay,0.0,float,"%f");
	BC_ASSERT_GREATER(linphone_call_get_audio_stats(c2)->round_trip_delay,0.0,float,"%f");
196
	if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
197
		BC_ASSERT_GREATER(linphone_call_get_video_stats(c1)->round_trip_delay,0.0,float,"%f");
198 199
	}
	if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
200
		BC_ASSERT_GREATER(linphone_call_get_video_stats(c2)->round_trip_delay,0.0,float,"%f");
201
	}
jehan's avatar
jehan committed
202 203
	linphone_call_unref(c1);
	linphone_call_unref(c2);
204 205
}

206 207 208 209 210 211 212 213
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);
	}
}

214
bool_t call_with_params2(LinphoneCoreManager* caller_mgr
215
						,LinphoneCoreManager* callee_mgr
216 217 218
						, const LinphoneCallTestParams *caller_test_params
						, const LinphoneCallTestParams *callee_test_params
						, bool_t build_callee_params) {
jehan's avatar
jehan committed
219
	int retry=0;
jehan's avatar
jehan committed
220 221
	stats initial_caller=caller_mgr->stat;
	stats initial_callee=callee_mgr->stat;
jehan's avatar
jehan committed
222
	bool_t result=FALSE;
223 224
	LinphoneCallParams *caller_params = caller_test_params->base;
	LinphoneCallParams *callee_params = callee_test_params->base;
225
	bool_t did_receive_call;
226
	LinphoneCall *callee_call=NULL;
227

228 229
	setup_sdp_handling(caller_test_params, caller_mgr);
	setup_sdp_handling(callee_test_params, callee_mgr);
230

231
	if (!caller_params){
232
		BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity));
Simon Morlat's avatar
Simon Morlat committed
233
	}else{
234
		BC_ASSERT_PTR_NOT_NULL(linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params));
Simon Morlat's avatar
Simon Morlat committed
235
	}
jehan's avatar
jehan committed
236

237
	did_receive_call = wait_for(callee_mgr->lc
238 239 240
				,caller_mgr->lc
				,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
				,initial_callee.number_of_LinphoneCallIncomingReceived+1);
241
	BC_ASSERT_EQUAL(did_receive_call, !callee_test_params->sdp_simulate_error, int, "%d");
242

243 244
	sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal);
	sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal);
245

246
	if (!did_receive_call) return 0;
247 248


249
	if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
250 251
		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
252

jehan's avatar
jehan committed
253

jehan's avatar
jehan committed
254 255
	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)
256
			&& retry++ < 100) {
jehan's avatar
jehan committed
257 258
			linphone_core_iterate(caller_mgr->lc);
			linphone_core_iterate(callee_mgr->lc);
259
			ms_usleep(20000);
jehan's avatar
jehan committed
260 261 262
	}


263
	BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1)
Simon Morlat's avatar
Simon Morlat committed
264
							||(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1));
jehan's avatar
jehan committed
265

jehan's avatar
jehan committed
266

267
	BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc));
268 269
	callee_call=linphone_core_get_call_by_remote_address2(callee_mgr->lc,caller_mgr->identity);

270
	if(!linphone_core_get_current_call(caller_mgr->lc) || !linphone_core_get_current_call(callee_mgr->lc) || !linphone_core_get_current_call_remote_address(callee_mgr->lc)) {
jehan's avatar
jehan committed
271
		return 0;
272
	} else if (caller_mgr->identity){
jehan's avatar
jehan committed
273 274
		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*/
275

jehan's avatar
jehan committed
276
		if (linphone_call_params_get_privacy(linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc))) == LinphonePrivacyNone) {
277 278
			/*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))
279
				BC_ASSERT_TRUE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(callee_call)));
jehan's avatar
jehan committed
280
		} else {
281
			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
282 283
		}
		linphone_address_destroy(callee_from);
jehan's avatar
jehan committed
284
	}
285 286


287
	if (callee_params){
288
		linphone_core_accept_call_with_params(callee_mgr->lc,callee_call,callee_params);
289
	}else if (build_callee_params){
290
		LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,callee_call);
291
		ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params));
292
		linphone_core_accept_call_with_params(callee_mgr->lc,callee_call,default_params);
293 294
		linphone_call_params_destroy(default_params);
	}else{
295
		linphone_core_accept_call(callee_mgr->lc,callee_call);
296
	}
jehan's avatar
jehan committed
297

298 299
	BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1));
	BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1));
300

jehan's avatar
jehan committed
301
	result = wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1)
jehan's avatar
jehan committed
302
			&&
jehan's avatar
jehan committed
303
			wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1);
jehan's avatar
jehan committed
304

jehan's avatar
jehan committed
305
	if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone
jehan's avatar
jehan committed
306
		|| linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) {
johan's avatar
johan committed
307
		/*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/
jehan's avatar
jehan committed
308 309
		if (	(linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
				|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS))
jehan's avatar
jehan committed
310
			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
311 312 313
		if ((linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionZRTP)
			|| (linphone_core_get_media_encryption(callee_mgr->lc) == LinphoneMediaEncryptionDTLS)
			|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS) /*also take care of caller policy*/ )
jehan's avatar
jehan committed
314 315
			wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1);
		{
316
			const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
317
			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
318
			call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc));
319
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc), int, "%d");
320

jehan's avatar
jehan committed
321
		}
jehan's avatar
jehan committed
322
	}
jehan's avatar
jehan committed
323 324 325 326 327 328 329 330
	/*wait ice re-invite*/
	if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce
			&& linphone_core_get_firewall_policy(callee_mgr->lc) == LinphonePolicyUseIce
			&& !linphone_core_sdp_200_ack_enabled(caller_mgr->lc)) { /*ice does not work with sdp less invite*/
		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));

	}
jehan's avatar
jehan committed
331
	return result;
jehan's avatar
jehan committed
332
}
333 334 335

bool_t call_with_params(LinphoneCoreManager* caller_mgr
						,LinphoneCoreManager* callee_mgr
336 337 338 339 340 341 342 343 344 345 346 347 348
						,const LinphoneCallParams *caller_params
						,const LinphoneCallParams *callee_params){
	LinphoneCallTestParams caller_test_params = {0}, callee_test_params =  {0};
	caller_test_params.base = (LinphoneCallParams*)caller_params;
	callee_test_params.base = (LinphoneCallParams*)caller_params;
	return call_with_params2(caller_mgr,callee_mgr,&caller_test_params,&callee_test_params,FALSE);
}

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

351 352 353
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);
}
354

Simon Morlat's avatar
Simon Morlat committed
355
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){
356
	return call_with_params(caller_mgr,callee_mgr,NULL,NULL);
Simon Morlat's avatar
Simon Morlat committed
357 358
}

359
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){
Simon Morlat's avatar
Simon Morlat committed
360
	linphone_core_terminate_all_calls(m1->lc);
361 362 363 364
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallReleased,1));
	BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallReleased,1));
Simon Morlat's avatar
Simon Morlat committed
365 366
}

jehan's avatar
jehan committed
367
void simple_call_base(bool_t enable_multicast_recv_side) {
368
	int begin;
Simon Morlat's avatar
Simon Morlat committed
369
	int leaked_objects;
370 371
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
372 373
	const LinphoneAddress *from;
	LinphoneCall *pauline_call;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
374
	LinphoneProxyConfig* marie_cfg;
375 376

	belle_sip_object_enable_leak_detector(TRUE);
377
	begin=belle_sip_object_get_object_count();
378

379
	marie = linphone_core_manager_new( "marie_rc");
380
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
381

382 383 384
	/* with the account manager, we might lose the identity */
	marie_cfg = linphone_core_get_default_proxy_config(marie->lc);
	{
385
		LinphoneAddress* marie_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(marie_cfg));
386 387 388
		char* marie_tmp_id = NULL;
		linphone_address_set_display_name(marie_addr, "Super Marie");
		marie_tmp_id = linphone_address_as_string(marie_addr);
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
389

390 391 392
		linphone_proxy_config_edit(marie_cfg);
		linphone_proxy_config_set_identity(marie_cfg,marie_tmp_id);
		linphone_proxy_config_done(marie_cfg);
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
393

394
		ms_free(marie_tmp_id);
395
		linphone_address_destroy(marie_addr);
396
	}
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
397

398
	linphone_core_enable_audio_multicast(pauline->lc,enable_multicast_recv_side);
jehan's avatar
jehan committed
399

400 401 402 403 404 405 406 407 408 409 410 411
	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");
412 413
			}
		}
414
	}
415 416


417 418 419
	liblinphone_tester_check_rtcp(marie,pauline);
	end_call(marie,pauline);
	linphone_core_manager_destroy(pauline);
420
	linphone_core_manager_destroy(marie);
Simon Morlat's avatar
Simon Morlat committed
421 422

	leaked_objects=belle_sip_object_get_object_count()-begin;
423
	BC_ASSERT_EQUAL(leaked_objects, 0, int, "%d");
Simon Morlat's avatar
Simon Morlat committed
424 425 426
	if (leaked_objects>0){
		belle_sip_object_dump_active_objects();
	}
jehan's avatar
jehan committed
427
}
428

jehan's avatar
jehan committed
429 430 431
static void simple_call() {
	simple_call_base(FALSE);
}
432

jehan's avatar
jehan committed
433 434 435 436 437 438 439 440 441 442
static void call_with_timeouted_bye(void) {
	int begin;
	int leaked_objects;
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
	belle_sip_timer_config_t timer_config;
	belle_sip_object_enable_leak_detector(TRUE);
	begin=belle_sip_object_get_object_count();

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

445
	BC_ASSERT_TRUE(call(marie,pauline));
jehan's avatar
jehan committed
446 447 448 449 450 451 452 453 454 455

	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;

	belle_sip_stack_set_timer_config(sal_get_belle_sip_stack(pauline->lc->sal),&timer_config);
	linphone_core_terminate_all_calls(pauline->lc);

456 457
	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
458 459 460 461

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

	linphone_core_terminate_all_calls(marie->lc);
462 463
	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
464 465 466 467 468

	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);

	leaked_objects=belle_sip_object_get_object_count()-begin;
469
	BC_ASSERT_EQUAL(leaked_objects, 0, int, "%d");
jehan's avatar
jehan committed
470 471 472 473 474
	if (leaked_objects>0){
		belle_sip_object_dump_active_objects();
	}
}

Simon Morlat's avatar
Simon Morlat committed
475 476 477 478 479
static void direct_call_over_ipv6(){
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;

	if (liblinphone_tester_ipv6_available()){
jehan's avatar
jehan committed
480 481
		LCSipTransports pauline_transports;
		LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp");
Simon Morlat's avatar
Simon Morlat committed
482
		marie = linphone_core_manager_new( "marie_rc");
483
		pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
jehan's avatar
jehan committed
484

Simon Morlat's avatar
Simon Morlat committed
485 486 487
		linphone_core_enable_ipv6(marie->lc,TRUE);
		linphone_core_enable_ipv6(pauline->lc,TRUE);
		linphone_core_set_default_proxy_config(marie->lc,NULL);
488 489
		/*wait for register in v6 mode, however sip2.linphone.org has an ipv6 address but doesn't listen to it*/
#if 0
490 491
		BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 2, 2000));
		BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 2, 2000));
492
#endif
493

jehan's avatar
jehan committed
494 495 496
		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);
497

498 499
		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));
Simon Morlat's avatar
Simon Morlat committed
500
		linphone_core_accept_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
501 502
		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));
503

Simon Morlat's avatar
Simon Morlat committed
504 505 506 507
		liblinphone_tester_check_rtcp(marie,pauline);
		end_call(marie,pauline);
		linphone_core_manager_destroy(marie);
		linphone_core_manager_destroy(pauline);
jehan's avatar
jehan committed
508
		linphone_address_destroy(pauline_dest);
Simon Morlat's avatar
Simon Morlat committed
509 510 511
	}else ms_warning("Test skipped, no ipv6 available");
}

512 513
static void call_outbound_with_multiple_proxy() {
	LinphoneCoreManager* marie   = linphone_core_manager_new2( "marie_rc", FALSE);
514
	LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_tcp_rc", FALSE);
515 516 517 518 519 520 521

	LinphoneProxyConfig* lpc = NULL;
	LinphoneProxyConfig* registered_lpc = linphone_proxy_config_new();

	linphone_core_get_default_proxy(marie->lc, &lpc);
	linphone_core_set_default_proxy(marie->lc,NULL);

522 523
	BC_ASSERT_FATAL(lpc != NULL);
	BC_ASSERT_FATAL(registered_lpc != NULL);
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538

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

	// set first LPC to unreacheable proxy addr
	linphone_proxy_config_edit(lpc);
	linphone_proxy_config_set_server_addr(lpc,"12.13.14.15:5223;transport=udp");
	linphone_proxy_config_set_route(lpc, "12.13.14.15:5223;transport=udp;lr");
	linphone_proxy_config_done(lpc);

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

541 542
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200));
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 2000));
543 544

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

547 548
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
549 550
}

551
#if 0 /* TODO: activate test when the implementation is ready */
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
552 553
static void multiple_answers_call() {
	/* Scenario is this: pauline calls marie, which is registered 2 times.
554
	   Both linphones answer at the same time, and only one should get the
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
555 556 557 558
	   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" );
559

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
560
	LinphoneCall* call1, *call2;
561

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
562 563 564
	MSList* lcs = ms_list_append(NULL,pauline->lc);
	lcs = ms_list_append(lcs,marie1->lc);
	lcs = ms_list_append(lcs,marie2->lc);
565 566


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

569
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
570

571 572 573
	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));
574

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
575 576 577
	// 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);
578

579 580
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
581

582 583
	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");
584

585 586 587
	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) );
588 589


Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
590 591 592
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
593 594 595
}
#endif

596
static void multiple_answers_call_with_media_relay(void) {
597

598
	/* Scenario is this: pauline calls marie, which is registered 2 times.
599
	 *   Both linphones answer at the same time, and only one should get the
600
	 *   call running, the other should be terminated */
601
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc" );
602 603
	LinphoneCoreManager* marie1  = linphone_core_manager_new( "marie_rc" );
	LinphoneCoreManager* marie2  = linphone_core_manager_new( "marie_rc" );
604

605
	LinphoneCall* call1, *call2;
606

607 608 609
	MSList* lcs = ms_list_append(NULL,pauline->lc);
	lcs = ms_list_append(lcs,marie1->lc);
	lcs = ms_list_append(lcs,marie2->lc);
610

611 612 613
	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);
614

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

617
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
618

619 620 621
	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));
622

623 624 625
	// 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);
626

627 628
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
629

630 631
	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");
632

633 634 635
	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) );
636 637


638 639 640
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
641 642
}

643
static void call_with_specified_codec_bitrate(void) {
644
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
645
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
646
	bool_t call_ok;
647
	const char * codec = "opus";
648
	int rate = 48000;
649
	int min_bw=24;
650
	int max_bw=50;
651

652 653
#ifdef __arm__
	if (ms_get_cpu_count() <2) { /*2 opus codec channel + resampler is too much for a single core*/
654
#ifndef ANDROID
655
		codec = "speex";
656 657 658
		rate = 8000;
		min_bw=20;
		max_bw=35;
659
#else
660
		BC_PASS("Test requires at least a dual core");
661 662
		goto end;
#endif
663 664
	}
#endif
665 666
	/*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)*/
667
	linphone_core_set_use_files(marie->lc, TRUE);
668 669

	if (linphone_core_find_payload_type(marie->lc,codec,rate,-1)==NULL){
670
		BC_PASS("opus codec not supported, test skipped.");
671 672
		goto end;
	}
673

674 675
	disable_all_audio_codecs_except_one(marie->lc,codec,rate);
	disable_all_audio_codecs_except_one(pauline->lc,codec,rate);
676

677
	linphone_core_set_payload_type_bitrate(marie->lc,
678
		linphone_core_find_payload_type(marie->lc,codec,rate,-1),
679
		max_bw);
680
	linphone_core_set_payload_type_bitrate(pauline->lc,
681
		linphone_core_find_payload_type(pauline->lc,codec,rate,-1),
682
		min_bw);
683

684
	BC_ASSERT_TRUE((call_ok=call(pauline,marie)));
685 686
	if (!call_ok) goto end;
	liblinphone_tester_check_rtcp(marie,pauline);
687 688
	/*wait a bit that bitstreams are stabilized*/
	wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
689

Simon Morlat's avatar
Simon Morlat committed
690 691 692 693 694 695
	BC_ASSERT_LOWER(linphone_core_manager_get_mean_audio_down_bw(marie), min_bw+5+min_bw*.1, int, "%i");
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(marie), 10, int, "%i"); /*check that at least something is received */
	BC_ASSERT_GREATER(linphone_core_manager_get_mean_audio_down_bw(pauline), (max_bw-5-max_bw*.1), int, "%i");
	linphone_core_terminate_all_calls(pauline->lc);
	BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
	BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
696 697 698 699 700
end:
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

701
static void simple_call_compatibility_mode(void) {
702
	char route[256];
703
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
704
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
705 706 707 708 709 710

	LinphoneCore* lc_marie=marie->lc;
	LinphoneCore* lc_pauline=pauline->lc;
	stats* stat_marie=&marie->stat;
	stats* stat_pauline=&pauline->stat;
	LinphoneProxyConfig* proxy;
711
	const LinphoneAddress* identity;
712 713 714 715 716
	LinphoneAddress* proxy_address;
	char*tmp;
	LCSipTransports transport;

	linphone_core_get_default_proxy(lc_marie,&proxy);
717
	BC_ASSERT_PTR_NOT_NULL (proxy);
718
	identity = linphone_proxy_config_get_identity_address(proxy);
719 720 721 722 723 724


	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);
725 726
	sprintf(route,"sip:%s",test_route);
	linphone_proxy_config_set_route(proxy,route);
727 728 729 730 731 732 733 734 735 736
	ms_free(tmp);
	linphone_address_destroy(proxy_address);
	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;