complex_sip_call_tester.c 11.1 KB
Newer Older
jehan's avatar
jehan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
	liblinphone_tester - liblinphone test suite
	Copyright (C) 2015  Belledonne Communications SARL

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "linphonecore.h"
#include "liblinphone_tester.h"
#include "lpconfig.h"
#include "private.h"

Simon Morlat's avatar
Simon Morlat committed
25 26 27 28 29
#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif

30 31
void check_rtcp(LinphoneCall *call) {
	MSTimeSpec ts;
32

33 34
	linphone_call_ref(call);
	liblinphone_tester_clock_start(&ts);
35

36
	do {
37
		if (linphone_call_get_audio_stats(call)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_get_video_stats(call)->round_trip_delay > 0.0)) {
38 39
			break;
		}
40
		wait_for_until(call->core, NULL, NULL, 0, 20); /*just to sleep while iterating*/
41
	} while (!liblinphone_tester_clock_elapsed(&ts, 15000));
42

43
	BC_ASSERT_GREATER(linphone_call_get_audio_stats(call)->round_trip_delay, 0.0, float, "%f");
44
	if (linphone_call_log_video_enabled(linphone_call_get_call_log(call))) {
45
		BC_ASSERT_GREATER(linphone_call_get_video_stats(call)->round_trip_delay, 0.0, float, "%f");
46
	}
47

48 49
	linphone_call_unref(call);
}
jehan's avatar
jehan committed
50 51 52 53 54

static FILE *sip_start(const char *senario, const char* dest_username, LinphoneAddress* dest_addres) {
	char *dest;
	char *command;
	FILE *file;
55

jehan's avatar
jehan committed
56 57 58 59
	if (linphone_address_get_port(dest_addres)>0)
		dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres));
	else
		dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres));
60

61 62
	//until errors logs are handled correctly and stop breaks output, they will be DISABLED
	command = ms_strdup_printf("sipp -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 2>/dev/null",senario,dest_username,dest);
63

jehan's avatar
jehan committed
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
	ms_message("Starting sipp commad [%s]",command);
	file = popen(command, "r");
	ms_free(command);
	ms_free(dest);
	return file;
}
/*static void dest_server_server_resolved(void *data, const char *name, struct addrinfo *ai_list) {
	*(struct addrinfo **)data =ai_list;
}*/
static void sip_update_within_icoming_reinvite_with_no_sdp(void) {
	LinphoneCoreManager *mgr;
/*	LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(mgr->lc);
	LinphoneAddress *dest = linphone_address_new(linphone_proxy_config_get_route(proxy) ?linphone_proxy_config_get_route(proxy):linphone_proxy_config_get_server_addr(proxy));
	struct addrinfo *addrinfo = NULL;
	char ipstring [INET6_ADDRSTRLEN];
	int err;
	int port = linphone_address_get_port(dest);*/
	char *identity_char;
jehan's avatar
jehan committed
82 83
	char *scen;
	FILE * sipp_out;
84

jehan's avatar
jehan committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
	/*currently we use direct connection because sipp do not properly set ACK request uri*/
	mgr= linphone_core_manager_new2( "empty_rc", FALSE);
	mgr->identity= linphone_core_get_primary_contact_parsed(mgr->lc);
	linphone_address_set_username(mgr->identity,"marie");
	identity_char=linphone_address_as_string(mgr->identity);
	linphone_core_set_primary_contact(mgr->lc,identity_char);
	linphone_core_iterate(mgr->lc);
	/*
	sal_resolve_a(	mgr->lc->sal
				  ,linphone_address_get_domain(dest)
				  ,linphone_address_get_port(dest)
				  ,AF_INET
				  ,(SalResolverCallback)dest_server_server_resolved
				  ,&addrinfo);
	linphone_address_destroy(dest);
	dest=linphone_address_new(NULL);
101

jehan's avatar
jehan committed
102
	wait_for(mgr->lc, mgr->lc, (int*)&addrinfo, 1);
103 104
	err=getnameinfo((struct sockaddr
	*)addrinfo->ai_addr,addrinfo->ai_addrlen,ipstring,INET6_ADDRSTRLEN,NULL,0,NI_NUMERICHOST);
jehan's avatar
jehan committed
105 106 107 108
	linphone_address_set_domain(dest, ipstring);
	if (port > 0)
		linphone_address_set_port(dest, port);
	*/
jehan's avatar
jehan committed
109
	scen = bc_tester_res("sipp/sip_update_within_icoming_reinvite_with_no_sdp.xml");
110
	sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);
jehan's avatar
jehan committed
111 112

	if (sipp_out) {
jehan's avatar
jehan committed
113
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
jehan's avatar
jehan committed
114
		linphone_core_accept_call(mgr->lc, linphone_core_get_current_call(mgr->lc));
jehan's avatar
jehan committed
115 116 117
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 2));
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
		pclose(sipp_out);
jehan's avatar
jehan committed
118
	}
jehan's avatar
jehan committed
119
	linphone_core_manager_destroy(mgr);
jehan's avatar
jehan committed
120 121
}

122 123 124 125 126 127
static void call_with_audio_mline_before_video_in_sdp() {
	LinphoneCoreManager *mgr;
	char *identity_char;
	char *scen;
	FILE * sipp_out;
	LinphoneCall *call = NULL;
128

129 130 131 132 133 134
	/*currently we use direct connection because sipp do not properly set ACK request uri*/
	mgr= linphone_core_manager_new2( "empty_rc", FALSE);
	mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
	linphone_address_set_username(mgr->identity,"marie");
	identity_char = linphone_address_as_string(mgr->identity);
	linphone_core_set_primary_contact(mgr->lc,identity_char);
135

136
	linphone_core_iterate(mgr->lc);
137

138
	scen = bc_tester_res("sipp/call_with_audio_mline_before_video_in_sdp.xml");
139

140 141 142 143 144 145 146 147 148 149 150
	sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);

	if (sipp_out) {
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
		call = linphone_core_get_current_call(mgr->lc);
		linphone_core_accept_call(mgr->lc, call);
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
		BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
		BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d");
		BC_ASSERT_TRUE(call->main_text_stream_index > 1);
		BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
151

152
		check_rtcp(call);
153

154 155 156 157 158 159
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
		pclose(sipp_out);
	}
	linphone_core_manager_destroy(mgr);
}

160 161 162 163 164 165
static void call_with_video_mline_before_audio_in_sdp() {
	LinphoneCoreManager *mgr;
	char *identity_char;
	char *scen;
	FILE * sipp_out;
	LinphoneCall *call = NULL;
166

167 168
	/*currently we use direct connection because sipp do not properly set ACK request uri*/
	mgr= linphone_core_manager_new2( "empty_rc", FALSE);
169
	mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
170
	linphone_address_set_username(mgr->identity,"marie");
171
	identity_char = linphone_address_as_string(mgr->identity);
172
	linphone_core_set_primary_contact(mgr->lc,identity_char);
173

174
	linphone_core_iterate(mgr->lc);
175

176
	scen = bc_tester_res("sipp/call_with_video_mline_before_audio_in_sdp.xml");
177

178 179 180 181 182 183 184 185 186
	sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);

	if (sipp_out) {
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
		call = linphone_core_get_current_call(mgr->lc);
		linphone_core_accept_call(mgr->lc, call);
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
		BC_ASSERT_EQUAL(call->main_audio_stream_index, 1, int, "%d");
		BC_ASSERT_EQUAL(call->main_video_stream_index, 0, int, "%d");
187 188
		BC_ASSERT_TRUE(call->main_text_stream_index > 1);
		BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
189

190
		check_rtcp(call);
191

192 193 194 195 196 197
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
		pclose(sipp_out);
	}
	linphone_core_manager_destroy(mgr);
}

198 199 200 201 202 203
static void call_with_multiple_audio_mline_in_sdp() {
	LinphoneCoreManager *mgr;
	char *identity_char;
	char *scen;
	FILE * sipp_out;
	LinphoneCall *call = NULL;
204

205 206 207 208 209 210
	/*currently we use direct connection because sipp do not properly set ACK request uri*/
	mgr= linphone_core_manager_new2( "empty_rc", FALSE);
	mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
	linphone_address_set_username(mgr->identity,"marie");
	identity_char = linphone_address_as_string(mgr->identity);
	linphone_core_set_primary_contact(mgr->lc,identity_char);
211

212
	linphone_core_iterate(mgr->lc);
213

214
	scen = bc_tester_res("sipp/call_with_multiple_audio_mline_in_sdp.xml");
215

216 217 218 219 220 221 222 223 224 225 226
	sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);

	if (sipp_out) {
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
		call = linphone_core_get_current_call(mgr->lc);
		linphone_core_accept_call(mgr->lc, call);
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
		BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
		BC_ASSERT_EQUAL(call->main_video_stream_index, 2, int, "%d");
		BC_ASSERT_TRUE(call->main_text_stream_index > 2);
		BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
227

228
		check_rtcp(call);
229

230 231 232 233 234 235
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
		pclose(sipp_out);
	}
	linphone_core_manager_destroy(mgr);
}

236 237 238 239 240 241
static void call_with_multiple_video_mline_in_sdp() {
	LinphoneCoreManager *mgr;
	char *identity_char;
	char *scen;
	FILE * sipp_out;
	LinphoneCall *call = NULL;
242

243 244 245 246 247 248
	/*currently we use direct connection because sipp do not properly set ACK request uri*/
	mgr= linphone_core_manager_new2( "empty_rc", FALSE);
	mgr->identity = linphone_core_get_primary_contact_parsed(mgr->lc);
	linphone_address_set_username(mgr->identity,"marie");
	identity_char = linphone_address_as_string(mgr->identity);
	linphone_core_set_primary_contact(mgr->lc,identity_char);
249

250
	linphone_core_iterate(mgr->lc);
251

252
	scen = bc_tester_res("sipp/call_with_multiple_video_mline_in_sdp.xml");
253

254 255 256 257 258 259 260 261 262 263 264
	sipp_out = sip_start(scen, linphone_address_get_username(mgr->identity), mgr->identity);

	if (sipp_out) {
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallIncomingReceived, 1));
		call = linphone_core_get_current_call(mgr->lc);
		linphone_core_accept_call(mgr->lc, call);
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallStreamsRunning, 1));
		BC_ASSERT_EQUAL(call->main_audio_stream_index, 0, int, "%d");
		BC_ASSERT_EQUAL(call->main_video_stream_index, 1, int, "%d");
		BC_ASSERT_TRUE(call->main_text_stream_index > 3);
		BC_ASSERT_TRUE(linphone_call_log_video_enabled(linphone_call_get_call_log(call)));
265

266
		check_rtcp(call);
267

268 269 270 271 272 273
		BC_ASSERT_TRUE(wait_for(mgr->lc, mgr->lc, &mgr->stat.number_of_LinphoneCallEnd, 1));
		pclose(sipp_out);
	}
	linphone_core_manager_destroy(mgr);
}

jehan's avatar
jehan committed
274
static test_t tests[] = {
275
	{ "SIP UPDATE within incoming reinvite without sdp", sip_update_within_icoming_reinvite_with_no_sdp },
276
	{ "Call with audio mline before video in sdp", call_with_audio_mline_before_video_in_sdp },
277
	{ "Call with video mline before audio in sdp", call_with_video_mline_before_audio_in_sdp },
278
	{ "Call with multiple audio mline in sdp", call_with_multiple_audio_mline_in_sdp },
279
	{ "Call with multiple video mline in sdp", call_with_multiple_video_mline_in_sdp },
jehan's avatar
jehan committed
280 281
};

jehan's avatar
jehan committed
282 283
test_suite_t complex_sip_call_test_suite = {
	"Complex SIP Call",
Sylvain Berfini's avatar
Sylvain Berfini committed
284 285 286
	NULL,
	NULL,
	liblinphone_tester_before_each,
287
	liblinphone_tester_after_each,
jehan's avatar
jehan committed
288 289 290
	sizeof(tests) / sizeof(tests[0]),
	tests
};