call_tester.c 276 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
static void srtp_call(void);
Simon Morlat's avatar
Simon Morlat committed
37
static char *create_filepath(const char *dir, const char *filename, const char *ext);
jehan's avatar
jehan committed
38

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

46

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

void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) {
	stats* counters = get_stats(lc);
86
	counters->number_of_LinphoneCallStatsUpdated++;
87
	if (lstats->updated & LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) {
88
		counters->number_of_rtcp_received++;
Simon Morlat's avatar
Simon Morlat committed
89 90 91
		if (lstats->rtcp_received_via_mux){
			counters->number_of_rtcp_received_via_mux++;
		}
92 93
	}
	if (lstats->updated & LINPHONE_CALL_STATS_SENT_RTCP_UPDATE ) {
94 95
		counters->number_of_rtcp_sent++;
	}
96 97 98 99
	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;

100 101 102 103
		counters->audio_download_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->download_bandwidth;
		counters->audio_upload_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->upload_bandwidth;
		counters->video_download_bandwidth[index] = (int)linphone_call_get_video_stats(call)->download_bandwidth;
		counters->video_upload_bandwidth[index] = (int)linphone_call_get_video_stats(call)->upload_bandwidth;
104
	}
105

106 107
}

jehan's avatar
jehan committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
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
124

jehan's avatar
jehan committed
125 126 127
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);
128
	stats* counters;
jehan's avatar
jehan committed
129 130 131 132
	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);

133
	counters = get_stats(lc);
jehan's avatar
jehan committed
134
	switch (new_call_state) {
jehan's avatar
jehan committed
135
	case LinphoneCallOutgoingInit :counters->number_of_LinphoneTransferCallOutgoingInit++;break;
136 137 138 139 140
	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;
141
	case LinphoneCallError :counters->number_of_LinphoneTransferCallError++;break;
jehan's avatar
jehan committed
142
	default:
143
		BC_FAIL("unexpected event");break;
jehan's avatar
jehan committed
144 145
	}
}
Ghislain MARY's avatar
Ghislain MARY committed
146

jehan's avatar
jehan committed
147

Simon Morlat's avatar
Simon Morlat committed
148
void linphone_call_iframe_decoded_cb(LinphoneCall *call,void * user_data) {
jehan's avatar
jehan committed
149 150
	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);
151
	stats* counters;
jehan's avatar
jehan committed
152 153 154 155
	LinphoneCore* lc=(LinphoneCore*)user_data;
	ms_message("call from [%s] to [%s] receive iFrame",from,to);
	ms_free(to);
	ms_free(from);
156
	counters = (stats*)get_stats(lc);
jehan's avatar
jehan committed
157 158
	counters->number_of_IframeDecoded++;
}
Simon Morlat's avatar
Simon Morlat committed
159

Simon Morlat's avatar
Simon Morlat committed
160
void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreManager* callee) {
161
	LinphoneCall *c1,*c2;
Simon Morlat's avatar
Simon Morlat committed
162
	MSTimeSpec ts;
jehan's avatar
jehan committed
163
	int max_time_to_wait;
164 165
	c1=linphone_core_get_current_call(caller->lc);
	c2=linphone_core_get_current_call(callee->lc);
166

167 168
	BC_ASSERT_PTR_NOT_NULL(c1);
	BC_ASSERT_PTR_NOT_NULL(c2);
169

Simon Morlat's avatar
Simon Morlat committed
170
	if (!c1 || !c2) return;
jehan's avatar
jehan committed
171 172
	linphone_call_ref(c1);
	linphone_call_ref(c2);
Simon Morlat's avatar
Simon Morlat committed
173
	liblinphone_tester_clock_start(&ts);
jehan's avatar
jehan committed
174 175 176 177
	if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc))
		max_time_to_wait = 15000;
	else
		max_time_to_wait = 5000;
178

Simon Morlat's avatar
Simon Morlat committed
179
	do {
180
		if (linphone_call_get_audio_stats(c1)->round_trip_delay > 0.0
jehan's avatar
jehan committed
181 182 183
			&& linphone_call_get_audio_stats(c2)->round_trip_delay > 0.0
			&& (!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)) {
184
			break;
185

186
		}
187
		wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/
jehan's avatar
jehan committed
188
	}while (!liblinphone_tester_clock_elapsed(&ts,max_time_to_wait));
189

jehan's avatar
jehan committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
	if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc)) {
		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");
		if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
			BC_ASSERT_GREATER(linphone_call_get_video_stats(c1)->round_trip_delay,0.0,float,"%f");
		}
		if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
			BC_ASSERT_GREATER(linphone_call_get_video_stats(c2)->round_trip_delay,0.0,float,"%f");
		}
	} else {
		if (linphone_core_rtcp_enabled(caller->lc)) {
			BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c1)->rtp_stats.sent_rtcp_packets, 0, int, "%i");
			BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c2)->rtp_stats.recv_rtcp_packets, 0, int, "%i");
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
				BC_ASSERT_EQUAL(linphone_call_get_video_stats(c1)->rtp_stats.sent_rtcp_packets, 0, int, "%i");
			}
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
				BC_ASSERT_EQUAL(linphone_call_get_video_stats(c2)->rtp_stats.recv_rtcp_packets, 0, int, "%i");
			}
		}
		if (linphone_core_rtcp_enabled(callee->lc)) {
		BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c2)->rtp_stats.sent_rtcp_packets, 0, int, "%i");
		BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c1)->rtp_stats.recv_rtcp_packets, 0, int, "%i");
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) {
				BC_ASSERT_EQUAL(linphone_call_get_video_stats(c1)->rtp_stats.recv_rtcp_packets, 0, int, "%i");
			}
			if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) {
				BC_ASSERT_EQUAL(linphone_call_get_video_stats(c2)->rtp_stats.sent_rtcp_packets, 0, int, "%i");
			}
		}

221
	}
jehan's avatar
jehan committed
222 223
	linphone_call_unref(c1);
	linphone_call_unref(c2);
224 225
}

226 227 228 229 230 231 232 233
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);
	}
}

234
bool_t call_with_params2(LinphoneCoreManager* caller_mgr
235
						,LinphoneCoreManager* callee_mgr
236 237 238
						, const LinphoneCallTestParams *caller_test_params
						, const LinphoneCallTestParams *callee_test_params
						, bool_t build_callee_params) {
jehan's avatar
jehan committed
239
	int retry=0;
jehan's avatar
jehan committed
240 241
	stats initial_caller=caller_mgr->stat;
	stats initial_callee=callee_mgr->stat;
jehan's avatar
jehan committed
242
	bool_t result=FALSE;
243 244
	LinphoneCallParams *caller_params = caller_test_params->base;
	LinphoneCallParams *callee_params = callee_test_params->base;
245
	bool_t did_receive_call;
246
	LinphoneCall *callee_call=NULL;
247
	LinphoneCall *caller_call=NULL;
248

249 250
	setup_sdp_handling(caller_test_params, caller_mgr);
	setup_sdp_handling(callee_test_params, callee_mgr);
251

252
	if (!caller_params){
253
		BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity)));
Simon Morlat's avatar
Simon Morlat committed
254
	}else{
255
		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
256
	}
257

258
	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
259

260
	did_receive_call = wait_for(callee_mgr->lc
261 262 263
				,caller_mgr->lc
				,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived
				,initial_callee.number_of_LinphoneCallIncomingReceived+1);
264
	BC_ASSERT_EQUAL(did_receive_call, !callee_test_params->sdp_simulate_error, int, "%d");
265

266 267
	sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal);
	sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal);
268

269
	if (!did_receive_call) return 0;
270 271


272
	if (linphone_core_get_calls_nb(callee_mgr->lc)<=1)
273 274
		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
275

jehan's avatar
jehan committed
276

jehan's avatar
jehan committed
277 278
	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)
279
			&& retry++ < 100) {
jehan's avatar
jehan committed
280 281
			linphone_core_iterate(caller_mgr->lc);
			linphone_core_iterate(callee_mgr->lc);
282
			ms_usleep(20000);
jehan's avatar
jehan committed
283 284 285
	}


286
	BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1)
Simon Morlat's avatar
Simon Morlat committed
287
							||(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1));
jehan's avatar
jehan committed
288

jehan's avatar
jehan committed
289

290
	BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc));
291 292
	callee_call=linphone_core_get_call_by_remote_address2(callee_mgr->lc,caller_mgr->identity);

293
	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
294
		return 0;
295
	} else if (caller_mgr->identity){
jehan's avatar
jehan committed
296 297
		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*/
298

jehan's avatar
jehan committed
299
		if (linphone_call_params_get_privacy(linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc))) == LinphonePrivacyNone) {
300 301
			/*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))
302
				BC_ASSERT_TRUE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(callee_call)));
jehan's avatar
jehan committed
303
		} else {
304
			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
305 306
		}
		linphone_address_destroy(callee_from);
jehan's avatar
jehan committed
307
	}
308 309


310
	if (callee_params){
311
		linphone_core_accept_call_with_params(callee_mgr->lc,callee_call,callee_params);
312
	}else if (build_callee_params){
313
		LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,callee_call);
314
		ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params));
315
		linphone_core_accept_call_with_params(callee_mgr->lc,callee_call,default_params);
316 317
		linphone_call_params_destroy(default_params);
	}else{
318
		linphone_core_accept_call(callee_mgr->lc,callee_call);
319
	}
jehan's avatar
jehan committed
320

321 322
	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));
323

324
	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
325
			&&
326
			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
327

jehan's avatar
jehan committed
328
	if (linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionNone
jehan's avatar
jehan committed
329
		|| linphone_core_get_media_encryption(callee_mgr->lc) != LinphoneMediaEncryptionNone) {
johan's avatar
johan committed
330
		/*wait for encryption to be on, in case of zrtp or dtls, it can take a few seconds*/
jehan's avatar
jehan committed
331 332
		if (	(linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionZRTP)
				|| (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS))
jehan's avatar
jehan committed
333
			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
334 335 336
		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
337 338
			wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1);
		{
339
			const LinphoneCallParams* call_param = linphone_call_get_current_params(callee_call);
340
			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
341
			call_param = linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc));
342
			BC_ASSERT_EQUAL(linphone_call_params_get_media_encryption(call_param),linphone_core_get_media_encryption(caller_mgr->lc), int, "%d");
343

jehan's avatar
jehan committed
344
		}
jehan's avatar
jehan committed
345
	}
jehan's avatar
jehan committed
346 347 348
	/*wait ice re-invite*/
	if (linphone_core_get_firewall_policy(caller_mgr->lc) == LinphonePolicyUseIce
			&& linphone_core_get_firewall_policy(callee_mgr->lc) == LinphonePolicyUseIce
349 350
			&& !linphone_core_sdp_200_ack_enabled(caller_mgr->lc) /*ice does not work with sdp less invite*/
			&& lp_config_get_int(callee_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE)
351 352
			&& lp_config_get_int(caller_mgr->lc->config, "sip", "update_call_when_ice_completed", TRUE)
			&& linphone_core_get_media_encryption(caller_mgr->lc) != LinphoneMediaEncryptionDTLS /*no ice-reinvite with DTLS*/) {
jehan's avatar
jehan committed
353 354 355
		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));

356 357 358 359
	} 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));
360

361 362 363 364 365 366 367 368
	}
	if (linphone_core_get_media_encryption(caller_mgr->lc) == LinphoneMediaEncryptionDTLS ) {
		if (linphone_core_get_current_call(caller_mgr->lc)->audiostream)
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&linphone_core_get_current_call(caller_mgr->lc)->audiostream->ms.sessions));
#ifdef VIDEO_ENABLED
		if (linphone_core_get_current_call(caller_mgr->lc)->videostream && video_stream_started(linphone_core_get_current_call(caller_mgr->lc)->videostream))
			BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&linphone_core_get_current_call(caller_mgr->lc)->videostream->ms.sessions));
#endif
369

jehan's avatar
jehan committed
370
	}
jehan's avatar
jehan committed
371
	return result;
jehan's avatar
jehan committed
372
}
373 374 375

bool_t call_with_params(LinphoneCoreManager* caller_mgr
						,LinphoneCoreManager* callee_mgr
376 377 378 379
						,const LinphoneCallParams *caller_params
						,const LinphoneCallParams *callee_params){
	LinphoneCallTestParams caller_test_params = {0}, callee_test_params =  {0};
	caller_test_params.base = (LinphoneCallParams*)caller_params;
380
	callee_test_params.base = (LinphoneCallParams*)callee_params;
381 382 383 384 385 386 387 388
	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);
389 390
}

391 392 393
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);
}
394

Simon Morlat's avatar
Simon Morlat committed
395
bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){
396
	return call_with_params(caller_mgr,callee_mgr,NULL,NULL);
Simon Morlat's avatar
Simon Morlat committed
397 398
}

399
void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){
400 401
	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
402
	linphone_core_terminate_all_calls(m1->lc);
403 404 405 406
	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
407 408
}

jehan's avatar
jehan committed
409
void simple_call_base(bool_t enable_multicast_recv_side) {
410 411
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
412 413
	const LinphoneAddress *from;
	LinphoneCall *pauline_call;
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
414
	LinphoneProxyConfig* marie_cfg;
415

416
	marie = linphone_core_manager_new( "marie_rc");
417
	pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
418

419 420 421
	/* with the account manager, we might lose the identity */
	marie_cfg = linphone_core_get_default_proxy_config(marie->lc);
	{
422
		LinphoneAddress* marie_addr = linphone_address_clone(linphone_proxy_config_get_identity_address(marie_cfg));
423 424 425
		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
426

427 428 429
		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
430

431
		ms_free(marie_tmp_id);
432
		linphone_address_destroy(marie_addr);
433
	}
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
434

435
	linphone_core_enable_audio_multicast(pauline->lc,enable_multicast_recv_side);
jehan's avatar
jehan committed
436

437 438 439 440 441 442 443 444 445 446 447 448
	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");
449 450
			}
		}
451
	}
452 453


454 455 456
	liblinphone_tester_check_rtcp(marie,pauline);
	end_call(marie,pauline);
	linphone_core_manager_destroy(pauline);
457
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
458
}
459

460
static void simple_call(void) {
jehan's avatar
jehan committed
461 462
	simple_call_base(FALSE);
}
463

464
static void automatic_call_termination(void) {
465 466 467 468 469 470 471 472 473 474
	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);
475

476 477 478 479 480 481 482 483 484 485
	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);
}

jehan's avatar
jehan committed
486 487 488 489 490 491
static void call_with_timeouted_bye(void) {
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;
	belle_sip_timer_config_t timer_config;

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

494
	BC_ASSERT_TRUE(call(marie,pauline));
jehan's avatar
jehan committed
495 496 497 498 499 500 501 502 503 504

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

505 506
	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
507 508 509 510

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

	linphone_core_terminate_all_calls(marie->lc);
511 512
	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
513 514 515 516 517

	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

518
static void direct_call_over_ipv6(void){
Simon Morlat's avatar
Simon Morlat committed
519 520 521 522
	LinphoneCoreManager* marie;
	LinphoneCoreManager* pauline;

	if (liblinphone_tester_ipv6_available()){
jehan's avatar
jehan committed
523 524
		LCSipTransports pauline_transports;
		LinphoneAddress* pauline_dest = linphone_address_new("sip:[::1];transport=tcp");
Simon Morlat's avatar
Simon Morlat committed
525
		marie = linphone_core_manager_new( "marie_rc");
526
		pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
jehan's avatar
jehan committed
527

Simon Morlat's avatar
Simon Morlat committed
528 529 530
		linphone_core_enable_ipv6(marie->lc,TRUE);
		linphone_core_enable_ipv6(pauline->lc,TRUE);
		linphone_core_set_default_proxy_config(marie->lc,NULL);
531 532
		/*wait for register in v6 mode, however sip2.linphone.org has an ipv6 address but doesn't listen to it*/
#if 0
533 534
		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));
535
#endif
536

jehan's avatar
jehan committed
537 538 539
		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);
540

541 542
		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
543
		linphone_core_accept_call(pauline->lc,linphone_core_get_current_call(pauline->lc));
544 545
		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));
546

Simon Morlat's avatar
Simon Morlat committed
547 548 549 550
		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
551
		linphone_address_destroy(pauline_dest);
Simon Morlat's avatar
Simon Morlat committed
552 553 554
	}else ms_warning("Test skipped, no ipv6 available");
}

555
static void call_outbound_with_multiple_proxy(void) {
556
	LinphoneCoreManager* marie   = linphone_core_manager_new2( "marie_rc", FALSE);
557
	LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_tcp_rc", FALSE);
558 559

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

562
	lpc = linphone_core_get_default_proxy_config(marie->lc);
563 564
	linphone_core_set_default_proxy(marie->lc,NULL);

565 566
	BC_ASSERT_FATAL(lpc != NULL);
	BC_ASSERT_FATAL(registered_lpc != NULL);
567 568 569 570 571 572 573 574

	// 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
575
	linphone_proxy_config_unref(registered_lpc);
576 577 578

	// set first LPC to unreacheable proxy addr
	linphone_proxy_config_edit(lpc);
579 580
	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");
581 582
	linphone_proxy_config_done(lpc);

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

585
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200));
586
	BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 10000));
587 588

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

591
	end_call(marie, pauline);
592 593
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
594 595
}

596
#if 0 /* TODO: activate test when the implementation is ready */
597
static void multiple_answers_call(void) {
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
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
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
600 601 602 603
	   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" );
604

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
605
	LinphoneCall* call1, *call2;
606

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
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
	BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000));
613

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

616 617 618
	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));
619

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
620 621 622
	// 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);
623

624 625
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
626

627 628
	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");
629

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


Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
635 636 637
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
638 639 640
}
#endif

641
static void multiple_answers_call_with_media_relay(void) {
642

643
	/* Scenario is this: pauline calls marie, which is registered 2 times.
644
	 *   Both linphones answer at the same time, and only one should get the
645
	 *   call running, the other should be terminated */
646
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc" );
647 648
	LinphoneCoreManager* marie1  = linphone_core_manager_new( "marie_rc" );
	LinphoneCoreManager* marie2  = linphone_core_manager_new( "marie_rc" );
649

650
	LinphoneCall* call1, *call2;
651

652 653 654
	MSList* lcs = ms_list_append(NULL,pauline->lc);
	lcs = ms_list_append(lcs,marie1->lc);
	lcs = ms_list_append(lcs,marie2->lc);
655

656 657 658
	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);
659

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

662
	BC_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) );
663

664 665 666
	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));
667

668 669 670
	// 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);
671

672 673
	BC_ASSERT_PTR_NOT_NULL_FATAL(call1);
	BC_ASSERT_PTR_NOT_NULL_FATAL(call2);
674

675 676
	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");
677

678 679 680
	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) );
681

Simon Morlat's avatar
Simon Morlat committed
682
	end_call(marie1, pauline);
683

684 685 686
	linphone_core_manager_destroy(pauline);
	linphone_core_manager_destroy(marie1);
	linphone_core_manager_destroy(marie2);
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
687 688
}

689
static void call_with_specified_codec_bitrate(void) {
690
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
691
	LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
692
	bool_t call_ok;
693
	const char * codec = "opus";
694
	int rate = 48000;
695
	int min_bw=24;
696
	int max_bw=50;
697

698
#ifdef __arm__
699
	if (ms_factory_get_cpu_count(marie->lc->factory) <2) { /*2 opus codec channel + resampler is too much for a single core*/
700
#ifndef ANDROID
701
		codec = "speex";
702 703 704
		rate = 8000;
		min_bw=20;
		max_bw=35;
705
#else
706
		BC_PASS("Test requires at least a dual core");
707 708
		goto end;
#endif
709 710
	}
#endif
711 712
	/*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)*/
713
	linphone_core_set_use_files(marie->lc, TRUE);
714 715

	if (linphone_core_find_payload_type(marie->lc,codec,rate,-1)==NULL){
716
		BC_PASS("opus codec not supported, test skipped.");
717 718
		goto end;
	}
719

720 721
	disable_all_audio_codecs_except_one(marie->lc,codec,rate);
	disable_all_audio_codecs_except_one(pauline->lc,codec,rate);
722

723
	linphone_core_set_payload_type_bitrate(marie->lc,