mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
fill media information when sending interval report too and added unit test for it (quality_reporting_interval_report)
This commit is contained in:
parent
ff6cbfc0f3
commit
11e43b1b28
5 changed files with 52 additions and 23 deletions
|
|
@ -869,7 +869,7 @@ LINPHONE_PUBLIC const char *linphone_proxy_config_get_quality_reporting_collecto
|
|||
/**
|
||||
* Set the interval between 2 interval reports sending when using quality reporting. If call exceed interval size, an
|
||||
* interval report will be sent to the collector. On call termination, a session report will be sent
|
||||
* for the remaining period. Value must be 0 (disabled) or greater than 120sec to avoid overloading.
|
||||
* for the remaining period. Value must be 0 (disabled) or positive.
|
||||
* @param[in] cfg #LinphoneProxyConfig object
|
||||
* @param[in] interval The interval in seconds, 0 means interval reports are disabled.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg)
|
|||
}
|
||||
|
||||
void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, uint8_t interval) {
|
||||
cfg->quality_reporting_interval = interval ? MAX(interval, 120) : 0;
|
||||
cfg->quality_reporting_interval = interval;
|
||||
}
|
||||
|
||||
int linphone_proxy_config_get_quality_reporting_interval(LinphoneProxyConfig *cfg) {
|
||||
|
|
@ -1216,6 +1216,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config
|
|||
const char *proxy;
|
||||
LinphoneProxyConfig *cfg;
|
||||
char key[50];
|
||||
int interval;
|
||||
|
||||
sprintf(key,"proxy_%i",index);
|
||||
|
||||
|
|
@ -1237,7 +1238,8 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config
|
|||
linphone_proxy_config_enable_quality_reporting(cfg,lp_config_get_int(config,key,"quality_reporting_enabled",0));
|
||||
tmp=lp_config_get_string(config,key,"quality_reporting_collector",NULL);
|
||||
if (tmp!=NULL) linphone_proxy_config_set_quality_reporting_collector(cfg,tmp);
|
||||
linphone_proxy_config_set_quality_reporting_interval(cfg, lp_config_get_int(config, key, "quality_reporting_interval", 0));
|
||||
interval=lp_config_get_int(config, key, "quality_reporting_interval", 0);
|
||||
linphone_proxy_config_set_quality_reporting_interval(cfg, interval? MAX(interval, 120) : 0);
|
||||
|
||||
linphone_proxy_config_set_contact_parameters(cfg,lp_config_get_string(config,key,"contact_parameters",NULL));
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ For codecs that are able to change sample rates, the lowest and highest sample r
|
|||
moslq == moscq
|
||||
valgrind
|
||||
video: what happens if doing stop/resume?
|
||||
one single report <- merge audio/video?
|
||||
unit test interval report
|
||||
rlq value: need algo to compute it
|
||||
3.4 overload avoidance?
|
||||
|
||||
|
|
@ -111,7 +113,7 @@ static void reset_avg_metrics(reporting_session_report_t * report){
|
|||
|
||||
metrics[i]->delay.round_trip_delay = 0;
|
||||
|
||||
metrics[i]->delay.symm_one_way_delay = 0;
|
||||
/*metrics[i]->delay.symm_one_way_delay = 0;*/
|
||||
}
|
||||
report->last_report_date = ms_time(NULL);
|
||||
}
|
||||
|
|
@ -147,15 +149,15 @@ static uint8_t are_metrics_filled(const reporting_content_metrics_t rm) {
|
|||
IF_NUM_IN_RANGE(rm.jitter_buffer.abs_max, 0, 65535, ret|=METRICS_JITTER_BUFFER);
|
||||
|
||||
IF_NUM_IN_RANGE(rm.delay.end_system_delay, 0, 65535, ret|=METRICS_DELAY);
|
||||
IF_NUM_IN_RANGE(rm.delay.symm_one_way_delay, 0, 65535, ret|=METRICS_DELAY);
|
||||
/*IF_NUM_IN_RANGE(rm.delay.symm_one_way_delay, 0, 65535, ret|=METRICS_DELAY);*/
|
||||
IF_NUM_IN_RANGE(rm.delay.interarrival_jitter, 0, 65535, ret|=METRICS_DELAY);
|
||||
IF_NUM_IN_RANGE(rm.delay.mean_abs_jitter, 0, 65535, ret|=METRICS_DELAY);
|
||||
|
||||
if (rm.signal.level != 127) ret|=METRICS_SIGNAL;
|
||||
if (rm.signal.noise_level != 127) ret|=METRICS_SIGNAL;
|
||||
|
||||
if (rm.adaptive_algorithm.input!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM;
|
||||
if (rm.adaptive_algorithm.output!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM;
|
||||
if (rm.qos_analyzer.input!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM;
|
||||
if (rm.qos_analyzer.output!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM;
|
||||
|
||||
if (rm.rtcp_xr_count>0){
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.nominal/rm.rtcp_xr_count, 0, 65535, ret|=METRICS_JITTER_BUFFER);
|
||||
|
|
@ -236,7 +238,7 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off
|
|||
}
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " ESD=%d", rm.delay.end_system_delay, 0, 65535);
|
||||
/*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " OWD=%d", rm.delay.one_way_delay, 0, 65535);*/
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " SOWD=%d", rm.delay.symm_one_way_delay, 0, 65535);
|
||||
/*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " SOWD=%d", rm.delay.symm_one_way_delay, 0, 65535);*/
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " IAJ=%d", rm.delay.interarrival_jitter, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " MAJ=%d", rm.delay.mean_abs_jitter, 0, 65535);
|
||||
}
|
||||
|
|
@ -271,8 +273,8 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off
|
|||
|
||||
if ((available_metrics & METRICS_ADAPTIVE_ALGORITHM) != 0){
|
||||
append_to_buffer(buffer, size, offset, "\r\nAdaptiveAlg:");
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " IN=%s", rm.adaptive_algorithm.input);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " OUT=%s", rm.adaptive_algorithm.output);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " IN=%s", rm.qos_analyzer.input);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " OUT=%s", rm.qos_analyzer.output);
|
||||
}
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\n");
|
||||
|
|
@ -395,11 +397,11 @@ static bool_t is_reporting_enabled(const LinphoneCall * call) {
|
|||
static void qos_analyser_on_action_suggested(void *user_data, const char * input, const char * output){
|
||||
reporting_content_metrics_t *metrics = (reporting_content_metrics_t*) user_data;
|
||||
char * newstr = NULL;
|
||||
newstr = ms_strdup_printf("%s%s;", metrics->adaptive_algorithm.input?metrics->adaptive_algorithm.input:"", input);
|
||||
STR_REASSIGN(metrics->adaptive_algorithm.input, newstr)
|
||||
newstr = ms_strdup_printf("%s%s;", metrics->qos_analyzer.input?metrics->qos_analyzer.input:"", input);
|
||||
STR_REASSIGN(metrics->qos_analyzer.input, newstr)
|
||||
|
||||
newstr = ms_strdup_printf("%s%s;", metrics->adaptive_algorithm.output?metrics->adaptive_algorithm.output:"", output);
|
||||
STR_REASSIGN(metrics->adaptive_algorithm.output, newstr)
|
||||
newstr = ms_strdup_printf("%s%s;", metrics->qos_analyzer.output?metrics->qos_analyzer.output:"", output);
|
||||
STR_REASSIGN(metrics->qos_analyzer.output, newstr)
|
||||
}
|
||||
|
||||
void linphone_reporting_update_ip(LinphoneCall * call) {
|
||||
|
|
@ -566,11 +568,13 @@ void linphone_reporting_publish_interval_report(LinphoneCall* call) {
|
|||
return;
|
||||
|
||||
if (call->log->reports[LINPHONE_CALL_STATS_AUDIO] != NULL) {
|
||||
linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_AUDIO);
|
||||
send_report(call, call->log->reports[LINPHONE_CALL_STATS_AUDIO], "VQIntervalReport");
|
||||
}
|
||||
|
||||
if (call->log->reports[LINPHONE_CALL_STATS_VIDEO] != NULL
|
||||
&& linphone_call_params_video_enabled(linphone_call_get_current_params(call))) {
|
||||
linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_VIDEO);
|
||||
send_report(call, call->log->reports[LINPHONE_CALL_STATS_VIDEO], "VQIntervalReport");
|
||||
}
|
||||
}
|
||||
|
|
@ -625,8 +629,8 @@ void linphone_reporting_destroy(reporting_session_report_t * report) {
|
|||
if (report->local_metrics.session_description.payload_desc != NULL) ms_free(report->local_metrics.session_description.payload_desc);
|
||||
if (report->remote_metrics.session_description.fmtp != NULL) ms_free(report->remote_metrics.session_description.fmtp);
|
||||
if (report->remote_metrics.session_description.payload_desc != NULL) ms_free(report->remote_metrics.session_description.payload_desc);
|
||||
if (report->local_metrics.adaptive_algorithm.input != NULL) ms_free(report->local_metrics.adaptive_algorithm.input);
|
||||
if (report->local_metrics.adaptive_algorithm.output != NULL) ms_free(report->local_metrics.adaptive_algorithm.output);
|
||||
if (report->local_metrics.qos_analyzer.input != NULL) ms_free(report->local_metrics.qos_analyzer.input);
|
||||
if (report->local_metrics.qos_analyzer.output != NULL) ms_free(report->local_metrics.qos_analyzer.output);
|
||||
|
||||
ms_free(report);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ typedef struct reporting_content_metrics {
|
|||
struct {
|
||||
int round_trip_delay; // no - vary
|
||||
int end_system_delay; // no - not implemented yet
|
||||
int symm_one_way_delay; // no - vary (depends on round_trip_delay) + not implemented (depends on end_system_delay)
|
||||
int symm_one_way_delay; // no - not implemented (depends on end_system_delay)
|
||||
int interarrival_jitter; // no - not implemented yet
|
||||
int mean_abs_jitter; // to check
|
||||
} delay;
|
||||
|
|
@ -94,11 +94,13 @@ typedef struct reporting_content_metrics {
|
|||
float moscq; // no - vary or avg - voip metrics - in [0..4.9]
|
||||
} quality_estimates;
|
||||
|
||||
// adaptive algorithm - custom extension
|
||||
// Quality of Service analyzer - custom extension
|
||||
/* This should allow us to analysis bad network conditions and quality adaptation
|
||||
on server side*/
|
||||
struct {
|
||||
char* input;
|
||||
char* output;
|
||||
} adaptive_algorithm;
|
||||
} qos_analyzer;
|
||||
|
||||
// for internal processing
|
||||
uint8_t rtcp_xr_count; // number of RTCP XR packets received since last report, used to compute average of instantaneous parameters as stated in the RFC 6035 (4.5)
|
||||
|
|
|
|||
|
|
@ -2202,7 +2202,6 @@ static void quality_reporting_not_sent_if_call_not_started() {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
static void quality_reporting_at_call_termination() {
|
||||
// int return_code = -1;
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
|
|
@ -2228,6 +2227,27 @@ static void quality_reporting_at_call_termination() {
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void quality_reporting_interval_report() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
|
||||
create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc));
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc));
|
||||
|
||||
// PUBLISH submission to the collector should be ok
|
||||
CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,15000));
|
||||
CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,15000));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
/*this is call forking with early media managed at client side (not by flexisip server)*/
|
||||
static void multiple_early_media(void) {
|
||||
|
|
@ -2374,9 +2394,10 @@ test_t call_tests[] = {
|
|||
{ "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite },
|
||||
{ "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error},
|
||||
{ "Call redirected by callee", call_redirect},
|
||||
{ "Call quality reporting not used if no config", quality_reporting_not_used_without_config},
|
||||
{ "Call quality reporting not sent if call did not start", quality_reporting_not_sent_if_call_not_started},
|
||||
{ "Call quality reporting sent if call ended normally", quality_reporting_at_call_termination},
|
||||
{ "Quality reporting not used if no config", quality_reporting_not_used_without_config},
|
||||
{ "Quality reporting session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started},
|
||||
{ "Quality reporting session report sent if call ended normally", quality_reporting_at_call_termination},
|
||||
{ "Quality reporting interval report if interval is configured", quality_reporting_interval_report},
|
||||
{ "Call with specified codec bitrate", call_with_specified_codec_bitrate}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue