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"
22
#include "quality_reporting.h"
23

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

27
void on_report_send_mandatory(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
28
	char * body = (char *)linphone_content_get_buffer(content);
29
	char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
30
	BC_ASSERT_TRUE(
31 32 33 34
			__strstr(body, "VQIntervalReport\r\n")			== body ||
			__strstr(body, "VQSessionReport\r\n")			== body ||
			__strstr(body, "VQSessionReport: CallTerm\r\n") == body
	);
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
	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="));
58 59

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

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

char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){
	if (metrics->rtcp_xr_count){
67 68 69
		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:"));
70
	}
71
	if (metrics->rtcp_sr_count+metrics->rtcp_xr_count>0){
72
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Delay:"));
73
	}
74
	if (metrics->rtcp_xr_count){
75
		BC_ASSERT_PTR_NOT_NULL(body=__strstr(body, "QualityEst:"));
76
	}
77 78 79 80

	return body;
}

81
void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
82
	char * body = (char*)linphone_content_get_buffer(content);
83
	char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
84
	reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type];
85
	on_report_send_mandatory(call,stream_type,content);
86 87
	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);
88
}
89
void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, SalStreamType stream_type, const LinphoneContent *content){
90
	char * body = (char*)linphone_content_get_buffer(content);
91
	reporting_session_report_t * report = linphone_quality_reporting_get_reports(linphone_call_log_get_quality_reporting(linphone_call_get_log(call)))[stream_type];
92 93 94

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

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


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

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

138
	if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL))  {
139
		// marie has stats collection enabled but pauline has not
140 141
		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)));
142

143
		// this field should be already filled
144 145
		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);
146

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

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

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

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

168 169
	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");
170

171
	if (bctbx_list_size(linphone_core_get_call_logs(marie->lc))>0) {
172
		out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data);
173 174
		BC_ASSERT_PTR_NOT_NULL(out_call_log);
		BC_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted, int, "%d");
175 176 177 178 179 180 181
	}
	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
182 183
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
184
end:
185 186 187
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
188

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

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

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

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

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

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

220 221
	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);
222

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

225 226
		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));
227
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,1, int, "%d");
228
		BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0, int, "%d");
229
	}
230 231 232 233
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

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

241 242
	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);
243

244
		linphone_core_terminate_all_calls(marie->lc);
245

246
		// now dialog id should be filled
247 248
		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);
249

250 251
		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));
252

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

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

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

271 272
	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);
273
		linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 1);
274

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

278
		// PUBLISH submission to the collector should be ok
279 280
		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
281
		end_call(marie, pauline);
282
	}
283 284 285 286
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

287
#ifdef VIDEO_ENABLED
288
static void quality_reporting_session_report_if_video_stopped(void) {
289
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
290
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
291
	LinphoneCall* call_pauline = NULL;
292
	LinphoneCall* call_marie = NULL;
293 294 295 296 297 298 299
	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);
300
	marie_params=linphone_core_create_call_params(marie->lc, NULL);
301
	linphone_call_params_enable_video(marie_params,TRUE);
302
	pauline_params=linphone_core_create_call_params(pauline->lc, NULL);
303 304
	linphone_call_params_enable_video(pauline_params,TRUE);

305 306
	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);
307

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

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

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

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

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

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

328 329
		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));
330
	}
Simon Morlat's avatar
Simon Morlat committed
331
	linphone_call_params_unref(marie_params);
332
	
333 334 335 336

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

339
void publish_report_with_route_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){
340 341
	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)));
342 343 344
	}
}

345
static void quality_reporting_sent_using_custom_route(void) {
346 347 348 349 350
	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;

Ghislain MARY's avatar
Ghislain MARY committed
351 352 353 354
	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);
355

356 357 358 359
	//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
360
		end_call(marie, pauline);
361 362 363 364 365 366 367 368 369 370 371

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

372
#ifdef VIDEO_ENABLED
373 374 375 376 377 378 379 380
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;
381

382 383 384 385
	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);
386
	marie_params=linphone_core_create_call_params(marie->lc, NULL);
387 388
	linphone_call_params_enable_video(marie_params,TRUE);
	linphone_call_params_enable_realtime_text(marie_params,TRUE);
389
	pauline_params=linphone_core_create_call_params(pauline->lc, NULL);
390 391 392 393 394
	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);
395
		linphone_proxy_config_set_quality_reporting_interval(linphone_call_get_dest_proxy(call_marie), 3);
396 397 398 399 400 401 402 403 404

		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
405 406
		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));
407

408 409 410 411
		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";
412
			size_t i;
413 414 415 416 417
			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]);
Ghislain MARY's avatar
Ghislain MARY committed
418
				BC_ASSERT_TRUE(wait_for_until(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneIsComposingActiveReceived, (int)i+1, 1000));
419 420 421 422
				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);
		}
Simon Morlat's avatar
Simon Morlat committed
423
		
424
		end_call(marie, pauline);
Simon Morlat's avatar
Simon Morlat committed
425
		/*wait that all publish complete*/
Simon Morlat's avatar
Simon Morlat committed
426
		BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,marie->stat.number_of_LinphonePublishProgress,60000));
427
	}
428

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

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

437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
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 };
	
	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);
	
	pol.automatically_accept = TRUE;
	pol.automatically_initiate = TRUE;
	linphone_core_set_video_policy(marie->lc, &pol);
	linphone_core_set_video_policy(pauline->lc, &pol);
	
	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);
	
	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");
		
		end_call(marie, pauline);
	}
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

472
test_t quality_reporting_tests[] = {
473 474 475 476 477 478
	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),
479
	#ifdef VIDEO_ENABLED
480 481
	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),
482
	#endif
483 484
	TEST_NO_TAG("Sent using custom route", quality_reporting_sent_using_custom_route),
	TEST_NO_TAG("Video bandwidth estimation", video_bandwidth_estimation)
485 486
};

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