quality_reporting_tester.c 22.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
	liblinphone_tester - liblinphone test suite
	Copyright (C) 2013  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 <stdio.h>
20
#include "linphone/core.h"
21
#include "liblinphone_tester.h"
Benjamin REIS's avatar
Benjamin REIS committed
22
#include "tester_utils.h"
23
#include "quality_reporting.h"
24

25 26 27
/*avoid crash if x is NULL on libc versions <4.5.26 */
#define __strstr(x, y) ((x==NULL)?NULL:strstr(x,y))

28
void on_report_send_mandatory(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
29
	char * body = (char *)linphone_content_get_buffer(content);
30
	char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
31
	BC_ASSERT_TRUE(
32 33 34 35
			__strstr(body, "VQIntervalReport\r\n")			== body ||
			__strstr(body, "VQSessionReport\r\n")			== body ||
			__strstr(body, "VQSessionReport: CallTerm\r\n") == body
	);
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "CallID:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalID:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteID:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "OrigID:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalGroup:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteGroup:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalAddr:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC="));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteAddr:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC="));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:"));
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "START="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "STOP="));

	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PT="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PD="));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SR="));
59 60

	/* We should have not reached RemoteMetrics section yet */
61
	BC_ASSERT_TRUE(!remote_metrics_start || body < remote_metrics_start);
62

63
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "DialogID:"));
64 65 66 67
}

char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){
	if (metrics->rtcp_xr_count){
68 69 70
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "JitterBuffer:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PacketLoss:"));
71
	}
72
	if (metrics->rtcp_sr_count+metrics->rtcp_xr_count>0){
73
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Delay:"));
74
	}
75
	if (metrics->rtcp_xr_count){
76
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "QualityEst:"));
77
	}
78 79 80 81

	return body;
}

82
void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
83
	char * body = (char*)linphone_content_get_buffer(content);
84
	char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
85
	reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type];
86
	on_report_send_mandatory(call,stream_type,content);
87 88
	BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:"));
	BC_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics,body) < remote_metrics_start);
89
}
90
void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
91
	char * body = (char*)linphone_content_get_buffer(content);
92
	reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type];
93 94 95

	on_report_send_mandatory(call,stream_type,content);
	if (report->remote_metrics.rtcp_sr_count+report->remote_metrics.rtcp_xr_count>0){
96 97
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteMetrics:"));
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:"));
98 99 100
		on_report_send_verify_metrics(&report->remote_metrics,body);
	}
}
101
void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
102 103 104 105
	on_report_send_with_rtcp_xr_local(call,stream_type,content);
	on_report_send_with_rtcp_xr_remote(call,stream_type,content);
}

106
bool_t create_call_for_quality_reporting_tests(
107 108 109
		LinphoneCoreManager* marie,
		LinphoneCoreManager* pauline,
		LinphoneCall** call_marie,
110 111 112 113 114 115 116
		LinphoneCall** call_pauline,
		LinphoneCallParams * params_marie,
		LinphoneCallParams * params_pauline
		) {


	bool_t call_succeeded = call_with_params(marie,pauline,params_marie,params_pauline);
117
	BC_ASSERT_TRUE(call_succeeded);
118 119 120
	if (call_succeeded) {
		if (call_marie) {
			*call_marie = linphone_core_get_current_call(marie->lc);
121
			BC_ASSERT_PTR_NOT_NULL(*call_marie);
122 123 124
		}
		if (call_pauline) {
			*call_pauline = linphone_core_get_current_call(pauline->lc);
125
			BC_ASSERT_PTR_NOT_NULL(*call_pauline);
126 127 128
		}
	}
	return call_succeeded;
129 130
}

131
static void quality_reporting_not_used_without_config(void) {
132
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
133
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
134 135
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;
136
	reporting_session_report_t **quality_reports = NULL;
Benjamin REIS's avatar
Benjamin REIS committed
137

138

139
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL))  {
140
		// marie has stats collection enabled but pauline has not
141 142
		BC_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(linphone_call_get_dest_proxy(call_marie)));
		BC_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(linphone_call_get_dest_proxy(call_pauline)));
143

144
		// this field should be already filled
145 146
		quality_reports = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call_marie)));
		BC_ASSERT_PTR_NOT_NULL(quality_reports[0]->info.local_addr.ip);
147

148
		// but not this one since it is updated at the end of call
149
		BC_ASSERT_PTR_NULL(quality_reports[0]->dialog_id);
Simon Morlat's avatar
Simon Morlat committed
150
		end_call(marie, pauline);
151
	}
152

153 154 155
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
156

157
static void quality_reporting_not_sent_if_call_not_started(void) {
158
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
159
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
160 161 162 163 164
	LinphoneCallLog* out_call_log;
	LinphoneCall* out_call;

	linphone_core_set_max_calls(pauline->lc,0);
	out_call = linphone_core_invite(marie->lc,"pauline");
165 166
	BC_ASSERT_PTR_NOT_NULL(out_call);
	if(out_call == NULL) goto end;
167 168
	linphone_call_ref(out_call);

169 170
	BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000));
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1, int, "%d");
171

172
	if (bctbx_list_size(linphone_core_get_call_logs(marie->lc))>0) {
173
		out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data);
174 175
		BC_ASSERT_PTR_NOT_NULL(out_call_log);
		BC_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted, int, "%d");
176 177 178 179 180 181 182
	}
	linphone_call_unref(out_call);

	// wait a few time...
	wait_for_until(marie->lc,NULL,NULL,0,1000);

	// since the callee was busy, there should be no publish to do
183 184
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
185
end:
186 187 188
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
189

190
static void quality_reporting_not_sent_if_low_bandwidth(void) {
191
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
192
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
193 194
	LinphoneCallParams* marie_params;

195
	marie_params=linphone_core_create_call_params(marie->lc, NULL);
196 197
	linphone_call_params_enable_low_bandwidth(marie_params,TRUE);

198
	if (create_call_for_quality_reporting_tests(marie, pauline, NULL, NULL, marie_params, NULL)) {
Simon Morlat's avatar
Simon Morlat committed
199
		end_call(marie, pauline);
200

201 202
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d");
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
203
	}
Simon Morlat's avatar
Simon Morlat committed
204
	linphone_call_params_unref(marie_params);
205 206 207 208
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

209
void on_report_send_remove_fields(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
210
	char *body = (char*)linphone_content_get_buffer(content);
211 212 213 214
	/*corrupt start of the report*/
	strncpy(body, "corrupted report is corrupted", strlen("corrupted report is corrupted"));
}

215
static void quality_reporting_invalid_report(void) {
216
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
217
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
218 219 220
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;

221 222
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) {
		linphone_reporting_set_on_report_send(call_marie, on_report_send_remove_fields);
223

Simon Morlat's avatar
Simon Morlat committed
224
		end_call(marie, pauline);
225

226 227
		BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1));
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishError,1,3000));
228
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,1, int, "%d");
229
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
230
	}
231 232 233 234
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

235
static void quality_reporting_at_call_termination(void) {
236
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
237
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr");
238 239
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;
240
	reporting_session_report_t **quality_reports = NULL;
241

242 243
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) {
		linphone_reporting_set_on_report_send(call_marie, on_report_send_with_rtcp_xr_remote);
244

245
		linphone_core_terminate_all_calls(marie->lc);
246

247
		// now dialog id should be filled
248 249
		quality_reports = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call_marie)));
		BC_ASSERT_PTR_NOT_NULL(quality_reports[0]->dialog_id);
250

251 252
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000));
		BC_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000));
253

254 255
		BC_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc));
		BC_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc));
256

257
		// PUBLISH submission to the collector should be ok
258
		BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1));
259
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d");
260
		BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1));
261
	}
262 263 264 265
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

266
static void quality_reporting_interval_report(void) {
267 268
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr");
269 270 271
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;

272 273
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL))  {
		linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory);
274
		linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 1);
275

276 277
		BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc));
		BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc));
278

279
		// PUBLISH submission to the collector should be ok
280 281
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,60000));
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,60000));
Simon Morlat's avatar
Simon Morlat committed
282
		end_call(marie, pauline);
283
	}
284 285 286 287
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

288
#ifdef VIDEO_ENABLED
289
static void quality_reporting_session_report_if_video_stopped(void) {
290
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
291
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
292
	LinphoneCall* call_pauline = NULL;
293
	LinphoneCall* call_marie = NULL;
294 295 296 297 298 299 300
	LinphoneCallParams* pauline_params;
	LinphoneCallParams* marie_params;

	linphone_core_enable_video_capture(marie->lc, TRUE);
	linphone_core_enable_video_display(marie->lc, FALSE);
	linphone_core_enable_video_capture(pauline->lc, TRUE);
	linphone_core_enable_video_display(pauline->lc, FALSE);
301
	marie_params=linphone_core_create_call_params(marie->lc, NULL);
302
	linphone_call_params_enable_video(marie_params,TRUE);
303
	pauline_params=linphone_core_create_call_params(pauline->lc, NULL);
304 305
	linphone_call_params_enable_video(pauline_params,TRUE);

306 307
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params)) {
		linphone_reporting_set_on_report_send(call_marie, on_report_send_with_rtcp_xr_local);
308

309 310
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d");
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
311

312 313
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000));
		BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline)));
314

315
		/*remove video*/
316 317
		linphone_call_params_unref(pauline_params);
		pauline_params=linphone_core_create_call_params(pauline->lc, call_pauline);
318
		linphone_call_params_enable_video(pauline_params,FALSE);
319
		linphone_call_update(call_pauline,pauline_params);
320
		linphone_call_params_unref(pauline_params);
321

322 323
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,10000));
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,10000));
324

325
		BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline)));
326

Simon Morlat's avatar
Simon Morlat committed
327
		end_call(marie, pauline);
328

329 330
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,2,5000));
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2,5000));
331
	}
Simon Morlat's avatar
Simon Morlat committed
332
	linphone_call_params_unref(marie_params);
Benjamin REIS's avatar
Benjamin REIS committed
333

334 335 336 337

	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
338
#endif
339

340
void publish_report_with_route_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){
341 342
	if (state == LinphonePublishProgress) {
		BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_event_get_resource(ev)), linphone_proxy_config_get_quality_reporting_collector(linphone_core_get_default_proxy_config(lc)));
343 344 345
	}
}

346
static void quality_reporting_sent_using_custom_route(void) {
347 348 349 350 351
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;

352 353 354 355
	LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
	linphone_core_cbs_set_publish_state_changed(cbs, publish_report_with_route_state_changed);
	linphone_core_add_callbacks(marie->lc, cbs);
	linphone_core_cbs_unref(cbs);
356

357 358 359 360
	//INVALID collector: sip.linphone.org do not collect reports, so it will throw a 404 Not Found error
	linphone_proxy_config_set_quality_reporting_collector(linphone_core_get_default_proxy_config(marie->lc), "sip:sip.linphone.org");

	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) {
Simon Morlat's avatar
Simon Morlat committed
361
		end_call(marie, pauline);
362 363 364 365 366 367 368 369 370 371 372

		// PUBLISH submission to the collector should be ERROR since route is not valid
		BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1));
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d");
		BC_ASSERT_TRUE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphonePublishError,1,10000));
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0,int, "%d");
	}
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

373
#ifdef VIDEO_ENABLED
374 375 376 377 378 379 380 381
static void quality_reporting_interval_report_video_and_rtt(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr");
	LinphoneCall* call_marie = NULL;
	LinphoneCall* call_pauline = NULL;
	LinphoneCallParams* pauline_params;
	LinphoneCallParams* marie_params;
 	LinphoneChatRoom *pauline_chat_room;
382

383 384 385 386
	linphone_core_enable_video_capture(marie->lc, TRUE);
	linphone_core_enable_video_display(marie->lc, FALSE);
	linphone_core_enable_video_capture(pauline->lc, TRUE);
	linphone_core_enable_video_display(pauline->lc, FALSE);
387
	marie_params=linphone_core_create_call_params(marie->lc, NULL);
388 389
	linphone_call_params_enable_video(marie_params,TRUE);
	linphone_call_params_enable_realtime_text(marie_params,TRUE);
390
	pauline_params=linphone_core_create_call_params(pauline->lc, NULL);
391 392 393 394 395
	linphone_call_params_enable_video(pauline_params,TRUE);
	linphone_call_params_enable_realtime_text(pauline_params,TRUE);

	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, marie_params, pauline_params))  {
		linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory);
396
		linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 3);
397 398 399 400 401 402 403 404 405

		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000));
		BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline)));
		BC_ASSERT_TRUE(linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call_pauline)));

		BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc));
		BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc));

		// PUBLISH submission to the collector should be ok
Simon Morlat's avatar
Simon Morlat committed
406 407
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,5000));
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,10000));
408

409 410 411 412
		pauline_chat_room = linphone_call_get_chat_room(call_pauline);
		BC_ASSERT_PTR_NOT_NULL(pauline_chat_room);
		if (pauline_chat_room) {
			const char* message = "Lorem Ipsum Belledonnum Communicatum";
413
			size_t i;
414 415 416 417 418
			LinphoneChatMessage* rtt_message = linphone_chat_room_create_message(pauline_chat_room,NULL);
			LinphoneChatRoom *marie_chat_room = linphone_call_get_chat_room(call_marie);

			for (i = 0; i < strlen(message); i++) {
				linphone_chat_message_put_char(rtt_message, message[i]);
419
				BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, (int)i+1, 1000));
420 421 422 423
				BC_ASSERT_EQUAL(linphone_chat_room_get_char(marie_chat_room), message[i], char, "%c");
			}
			linphone_chat_room_send_chat_message(pauline_chat_room, rtt_message);
		}
Benjamin REIS's avatar
Benjamin REIS committed
424

425
		end_call(marie, pauline);
Simon Morlat's avatar
Simon Morlat committed
426
		/*wait that all publish complete*/
427
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,marie->stat.number_of_LinphonePublishProgress,60000));
428
	}
429

Simon Morlat's avatar
Simon Morlat committed
430 431
	linphone_call_params_unref(marie_params);
	linphone_call_params_unref(pauline_params);
432

433 434 435
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
436
#endif
437

438 439 440 441 442
static void video_bandwidth_estimation(void){
	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
	LinphoneVideoPolicy pol = {0};
	OrtpNetworkSimulatorParams simparams = { 0 };
Benjamin REIS's avatar
Benjamin REIS committed
443

444 445 446 447 448
	linphone_core_set_video_device(marie->lc, "Mire: Mire (synthetic moving picture)");
	linphone_core_enable_video_capture(marie->lc, TRUE);
	linphone_core_enable_video_display(marie->lc, TRUE);
	linphone_core_enable_video_capture(pauline->lc, TRUE);
	linphone_core_enable_video_display(pauline->lc, TRUE);
Benjamin REIS's avatar
Benjamin REIS committed
449

450 451 452 453
	pol.automatically_accept = TRUE;
	pol.automatically_initiate = TRUE;
	linphone_core_set_video_policy(marie->lc, &pol);
	linphone_core_set_video_policy(pauline->lc, &pol);
Benjamin REIS's avatar
Benjamin REIS committed
454

455 456 457 458 459
	linphone_core_set_preferred_video_size_by_name(marie->lc, "vga");
	simparams.mode = OrtpNetworkSimulatorOutbound;
	simparams.enabled = TRUE;
	simparams.max_bandwidth = 300000;
	linphone_core_set_network_simulator_params(marie->lc, &simparams);
Benjamin REIS's avatar
Benjamin REIS committed
460

461 462 463 464 465
	if (BC_ASSERT_TRUE(call(marie, pauline))){
		/*wait for the first TMMBR*/
		BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_tmmbr_received, 1, 50000));
		BC_ASSERT_GREATER((float)marie->stat.last_tmmbr_value_received, 270000.f, float, "%f");
		BC_ASSERT_LOWER((float)marie->stat.last_tmmbr_value_received, 330000.f, float, "%f");
Benjamin REIS's avatar
Benjamin REIS committed
466

467 468 469 470 471 472
		end_call(marie, pauline);
	}
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

473
test_t quality_reporting_tests[] = {
474 475 476 477 478 479
	TEST_NO_TAG("Not used if no config", quality_reporting_not_used_without_config),
	TEST_NO_TAG("Call term session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started),
	TEST_NO_TAG("Call term session report not sent if low bandwidth", quality_reporting_not_sent_if_low_bandwidth),
	TEST_NO_TAG("Call term session report invalid if missing mandatory fields", quality_reporting_invalid_report),
	TEST_NO_TAG("Call term session report sent if call ended normally", quality_reporting_at_call_termination),
	TEST_NO_TAG("Interval report if interval is configured", quality_reporting_interval_report),
480
	#ifdef VIDEO_ENABLED
481 482
	TEST_NO_TAG("Interval report if interval is configured with video and realtime text", quality_reporting_interval_report_video_and_rtt),
	TEST_NO_TAG("Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped),
483
	#endif
484 485
	TEST_NO_TAG("Sent using custom route", quality_reporting_sent_using_custom_route),
	TEST_NO_TAG("Video bandwidth estimation", video_bandwidth_estimation)
486 487
};

488
test_suite_t quality_reporting_test_suite = {"QualityReporting", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
489 490
											 sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]),
											 quality_reporting_tests};