static mblk_t * make_rtcp_fb_fir(RtpSession *session) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_fir_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_fir_fci_t *fci; /* Fill FIR */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_fir_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_fir_fci_t); fbh->packet_sender_ssrc = htonl(0); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); fci->ssrc = htonl(rtp_session_get_send_ssrc(session)); fci->seq_nr = session->rtcp.rtcp_fb_fir_seq_nr++; fci->pad1 = 0; fci->pad2 = 0; /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_FIR, msgdsize(h)); return h; }
int media_stream_set_srtp_recv_key(MediaStream *stream, MSCryptoSuite suite, const char* key){ if (!media_stream_srtp_supported()) { ms_error("ortp srtp support disabled in oRTP or mediastreamer2"); return -1; } #ifdef ORTP_HAVE_SRTP { uint32_t ssrc,send_ssrc; bool_t updated=FALSE; if (check_srtp_session_created(stream)==-1) return -1; /*check if a previous key was configured, in which case remove it*/ send_ssrc=rtp_session_get_send_ssrc(stream->sessions.rtp_session); ssrc=find_other_ssrc(stream->sessions.srtp_session,htonl(send_ssrc)); /*careful: remove_stream takes the SSRC in network byte order...*/ if (ortp_srtp_remove_stream(stream->sessions.srtp_session,ssrc)==0) updated=TRUE; ssrc=rtp_session_get_recv_ssrc(stream->sessions.rtp_session); ms_message("media_stream_set_srtp_recv_key(): %s key %s",updated ? "changing to" : "starting with", key); return add_srtp_stream(stream->sessions.srtp_session,suite,ssrc,key,TRUE); } #else return -1; #endif }
static mblk_t * make_rtcp_fb_sli(RtpSession *session, uint16_t first, uint16_t number, uint8_t picture_id) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_sli_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_sli_fci_t *fci; /* Fill SLI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_sli_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_sli_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); rtcp_fb_sli_fci_set_first(fci, first); rtcp_fb_sli_fci_set_number(fci, number); rtcp_fb_sli_fci_set_picture_id(fci, picture_id); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_SLI, msgdsize(h)); return h; }
static int rtcp_xr_stat_summary_init(uint8_t *buf, RtpSession *session) { rtcp_xr_stat_summary_report_block_t *block = (rtcp_xr_stat_summary_report_block_t *)buf; uint16_t last_rcv_seq = session->rtp.hwrcv_extseq & 0xFFFF; uint8_t flags = session->rtcp.xr_conf.stat_summary_flags; uint32_t expected_packets; uint32_t lost_packets = 0; uint32_t dup_packets = session->rtcp_xr_stats.dup_since_last_stat_summary; /* Compute lost and duplicate packets statistics */ if (flags & OrtpRtcpXrStatSummaryLoss) { uint32_t no_duplicate_received = session->rtcp_xr_stats.rcv_since_last_stat_summary - dup_packets; expected_packets = last_rcv_seq - session->rtcp_xr_stats.rcv_seq_at_last_stat_summary; lost_packets = (expected_packets > session->rtcp_xr_stats.rcv_since_last_stat_summary) ? (expected_packets - no_duplicate_received) : 0; } block->bh.bt = RTCP_XR_STAT_SUMMARY; block->bh.flags = flags; block->bh.length = htons(9); block->ssrc = htonl(rtp_session_get_recv_ssrc(session)); block->begin_seq = htons(session->rtcp_xr_stats.rcv_seq_at_last_stat_summary + 1); block->end_seq = htons(last_rcv_seq + 1); block->lost_packets = htonl(lost_packets); block->dup_packets = htonl(dup_packets); if ((flags & OrtpRtcpXrStatSummaryJitt) && (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)) { block->min_jitter = htonl(session->rtcp_xr_stats.min_jitter_since_last_stat_summary); block->max_jitter = htonl(session->rtcp_xr_stats.max_jitter_since_last_stat_summary); block->mean_jitter = htonl((session->rtcp_xr_stats.rcv_since_last_stat_summary > 1) ? (uint32_t)session->rtcp_xr_stats.newm_jitter_since_last_stat_summary : 0); block->dev_jitter = htonl((session->rtcp_xr_stats.rcv_since_last_stat_summary > 2) ? (uint32_t)sqrt(session->rtcp_xr_stats.news_jitter_since_last_stat_summary / (session->rtcp_xr_stats.rcv_since_last_stat_summary - 2)) : 0); } else { block->min_jitter = htonl(0); block->max_jitter = htonl(0); block->mean_jitter = htonl(0); block->dev_jitter = htonl(0); } if ((flags & (OrtpRtcpXrStatSummaryTTL | OrtpRtcpXrStatSummaryHL)) && (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0)) { block->min_ttl_or_hl = session->rtcp_xr_stats.min_ttl_or_hl_since_last_stat_summary; block->max_ttl_or_hl = session->rtcp_xr_stats.max_ttl_or_hl_since_last_stat_summary; block->mean_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 0) ? (uint8_t)session->rtcp_xr_stats.newm_ttl_or_hl_since_last_stat_summary : 0; block->dev_ttl_or_hl = (session->rtcp_xr_stats.rcv_since_last_stat_summary > 1) ? (uint8_t)sqrt(session->rtcp_xr_stats.news_ttl_or_hl_since_last_stat_summary / (session->rtcp_xr_stats.rcv_since_last_stat_summary - 1)) : 0; } else { block->min_ttl_or_hl = 0; block->max_ttl_or_hl = 0; block->mean_ttl_or_hl = 0; block->dev_ttl_or_hl = 0; } session->rtcp_xr_stats.rcv_seq_at_last_stat_summary = last_rcv_seq; session->rtcp_xr_stats.rcv_since_last_stat_summary = 0; session->rtcp_xr_stats.dup_since_last_stat_summary = 0; return sizeof(rtcp_xr_stat_summary_report_block_t); }
void rtp_session_send_rtcp_fb_tmmbr(RtpSession *session, uint64_t mxtbr) { mblk_t *m; if ((rtp_session_avpf_enabled(session) == TRUE) && (rtp_session_avpf_feature_enabled(session, ORTP_AVPF_FEATURE_TMMBR) == TRUE)) { if ((rtp_session_rtcp_rtpfb_scheduled(session, RTCP_RTPFB_TMMBR) != TRUE) && (rtp_session_get_recv_ssrc(session) != 0)) { uint16_t overhead = (session->rtp.gs.sockfamily == AF_INET6) ? IP6_UDP_OVERHEAD : IP_UDP_OVERHEAD; m = make_rtcp_fb_tmmbr(session, mxtbr, overhead); rtp_session_add_fb_packet_to_send(session, m); session->rtcp.send_algo.tmmbr_scheduled = TRUE; } rtp_session_send_fb_rtcp_packet_and_reschedule(session); } }
static mblk_t * make_rtcp_fb_rpsi(RtpSession *session, uint8_t *bit_string, uint16_t bit_string_len) { uint16_t bit_string_len_in_bytes; int additional_bytes; int size; mblk_t *h; rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_rpsi_fci_t *fci; int i; /* Calculate packet size and allocate memory. */ bit_string_len_in_bytes = (bit_string_len / 8) + (((bit_string_len % 8) == 0) ? 0 : 1); additional_bytes = bit_string_len_in_bytes - 2; if (additional_bytes < 0) additional_bytes = 0; size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_rpsi_fci_t) + additional_bytes; h = allocb(size, 0); /* Fill RPSI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_rpsi_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_rpsi_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); if (bit_string_len <= 16) { fci->pb = 16 - bit_string_len; memset(&fci->bit_string, 0, 2); } else { fci->pb = (bit_string_len - 16) % 32; memset(&fci->bit_string, 0, bit_string_len_in_bytes); } fci->payload_type = rtp_session_get_recv_payload_type(session) & 0x7F; memcpy(&fci->bit_string, bit_string, bit_string_len / 8); for (i = 0; i < (bit_string_len % 8); i++) { fci->bit_string[bit_string_len_in_bytes - 1] |= (bit_string[bit_string_len_in_bytes - 1] & (1 << (7 - i))); } /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_RPSI, msgdsize(h)); return h; }
static mblk_t * make_rtcp_fb_pli(RtpSession *session) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t); mblk_t *h= allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; /* Fill PLI */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(rtp_session_get_recv_ssrc(session)); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_PSFB, RTCP_PSFB_PLI, msgdsize(h)); return h; }
static int rtcp_xr_dlrr_init(uint8_t *buf, RtpSession *session) { uint32_t dlrr = 0; rtcp_xr_dlrr_report_block_t *block = (rtcp_xr_dlrr_report_block_t *)buf; block->bh.bt = RTCP_XR_DLRR; block->bh.flags = 0; // Reserved bits block->bh.length = htons(3); block->content[0].ssrc = htonl(rtp_session_get_recv_ssrc(session)); block->content[0].lrr = htonl(session->rtcp_xr_stats.last_rcvr_rtt_ts); if (session->rtcp_xr_stats.last_rcvr_rtt_time.tv_sec != 0) { struct timeval now; double delay; ortp_gettimeofday(&now, NULL); delay = ((now.tv_sec - session->rtcp_xr_stats.last_rcvr_rtt_time.tv_sec) + ((now.tv_usec - session->rtcp_xr_stats.last_rcvr_rtt_time.tv_usec) * 1e-6)) * 65536; dlrr = (uint32_t) delay; } block->content[0].dlrr = htonl(dlrr); return sizeof(rtcp_xr_dlrr_report_block_t); }
static mblk_t * make_rtcp_fb_tmmbr(RtpSession *session, uint64_t mxtbr, uint16_t measured_overhead) { int size = sizeof(rtcp_common_header_t) + sizeof(rtcp_fb_header_t) + sizeof(rtcp_fb_tmmbr_fci_t); mblk_t *h = allocb(size, 0); rtcp_common_header_t *ch; rtcp_fb_header_t *fbh; rtcp_fb_tmmbr_fci_t *fci; uint8_t mxtbr_exp = 0; uint32_t mxtbr_mantissa = 0; /* Compute mxtbr exp and mantissa */ while (mxtbr >= (1 << 17)) { mxtbr >>= 1; mxtbr_exp++; } mxtbr_mantissa = mxtbr & 0x0001FFFF; /* Fill TMMBR */ ch = (rtcp_common_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_common_header_t); fbh = (rtcp_fb_header_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_header_t); fci = (rtcp_fb_tmmbr_fci_t *)h->b_wptr; h->b_wptr += sizeof(rtcp_fb_tmmbr_fci_t); fbh->packet_sender_ssrc = htonl(rtp_session_get_send_ssrc(session)); fbh->media_source_ssrc = htonl(0); fci->ssrc = htonl(rtp_session_get_recv_ssrc(session)); rtcp_fb_tmmbr_fci_set_mxtbr_exp(fci, mxtbr_exp); rtcp_fb_tmmbr_fci_set_mxtbr_mantissa(fci, mxtbr_mantissa); rtcp_fb_tmmbr_fci_set_measured_overhead(fci, measured_overhead); /* Fill common header */ rtcp_common_header_init(ch, session, RTCP_RTPFB, RTCP_RTPFB_TMMBR, msgdsize(h)); /* Store packet to be able to retransmit. */ if (session->rtcp.tmmbr_info.sent) freemsg(session->rtcp.tmmbr_info.sent); session->rtcp.tmmbr_info.sent = copymsg(h); return h; }
void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { MediaStream * stream = NULL; const PayloadType * local_payload = NULL; const PayloadType * remote_payload = NULL; const LinphoneCallParams * current_params = linphone_call_get_current_params(call); reporting_session_report_t * report = call->log->reporting.reports[stats_type]; char * dialog_id; // call->op might be already released if hanging up in state LinphoneCallOutgoingInit if (!media_report_enabled(call, stats_type) || call->op == NULL) return; dialog_id = sal_op_get_dialog_id(call->op); STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id)); STR_REASSIGN(report->local_metrics.user_agent, ms_strdup(linphone_core_get_user_agent(call->core))); STR_REASSIGN(report->remote_metrics.user_agent, ms_strdup(linphone_call_get_remote_user_agent(call))); // RFC states: "LocalGroupID provides the identification for the purposes // of aggregation for the local endpoint.". STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s" , dialog_id ? dialog_id : "" , "local" , report->local_metrics.user_agent ? report->local_metrics.user_agent : "" ) ); STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s" , dialog_id ? dialog_id : "" , "remote" , report->remote_metrics.user_agent ? report->remote_metrics.user_agent : "" ) ); if (call->dir == LinphoneCallIncoming) { STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->from)); STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->to)); STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.remote_addr.id)); } else { STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->to)); STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->from)); STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.local_addr.id)); } report->local_metrics.timestamps.start = call->log->start_date_time; report->local_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call); /*we use same timestamps for remote too*/ report->remote_metrics.timestamps.start = call->log->start_date_time; report->remote_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call); /*yet we use the same payload config for local and remote, since this is the largest use case*/ if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) { stream = &call->audiostream->ms; local_payload = linphone_call_params_get_used_audio_codec(current_params); remote_payload = local_payload; } else if (stats_type == LINPHONE_CALL_STATS_VIDEO && call->videostream != NULL) { stream = &call->videostream->ms; local_payload = linphone_call_params_get_used_video_codec(current_params); remote_payload = local_payload; } else if (stats_type == LINPHONE_CALL_STATS_TEXT && call->textstream != NULL) { stream = &call->textstream->ms; local_payload = linphone_call_params_get_used_text_codec(current_params); remote_payload = local_payload; } if (stream != NULL) { RtpSession * session = stream->sessions.rtp_session; report->info.local_addr.ssrc = rtp_session_get_send_ssrc(session); report->info.remote_addr.ssrc = rtp_session_get_recv_ssrc(session); if (stream->qi != NULL){ report->local_metrics.quality_estimates.moslq = ms_quality_indicator_get_average_lq_rating(stream->qi) >= 0 ? MAX(1, ms_quality_indicator_get_average_lq_rating(stream->qi)) : -1; report->local_metrics.quality_estimates.moscq = ms_quality_indicator_get_average_rating(stream->qi) >= 0 ? MAX(1, ms_quality_indicator_get_average_rating(stream->qi)) : -1; } } STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id ? dialog_id : "", report->info.local_addr.ssrc)); if (local_payload != NULL) { report->local_metrics.session_description.payload_type = local_payload->type; if (local_payload->mime_type!=NULL) STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type)); report->local_metrics.session_description.sample_rate = local_payload->clock_rate; if (local_payload->recv_fmtp!=NULL) STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp)); } if (remote_payload != NULL) { report->remote_metrics.session_description.payload_type = remote_payload->type; STR_REASSIGN(report->remote_metrics.session_description.payload_desc, ms_strdup(remote_payload->mime_type)); report->remote_metrics.session_description.sample_rate = remote_payload->clock_rate; STR_REASSIGN(report->remote_metrics.session_description.fmtp, ms_strdup(remote_payload->recv_fmtp)); } ms_free(dialog_id); }
static int rtcp_xr_voip_metrics_init(uint8_t *buf, RtpSession *session) { JBParameters jbparams; uint32_t expected_packets; uint32_t lost_packets; rtcp_xr_voip_metrics_report_block_t *block = (rtcp_xr_voip_metrics_report_block_t *)buf; float rtt = rtp_session_get_round_trip_propagation(session); uint16_t int_rtt = (rtt >= 0) ? (rtt * 1000) : 0; float qi = -1; float lq_qi = -1; rtp_session_get_jitter_buffer_params(session, &jbparams); if (session->rtcp.xr_media_callbacks.average_qi != NULL) { qi = session->rtcp.xr_media_callbacks.average_qi(session->rtcp.xr_media_callbacks.userdata); } if (session->rtcp.xr_media_callbacks.average_lq_qi != NULL) { lq_qi = session->rtcp.xr_media_callbacks.average_lq_qi(session->rtcp.xr_media_callbacks.userdata); } block->bh.bt = RTCP_XR_VOIP_METRICS; block->bh.flags = 0; // Reserved bits block->bh.length = htons(8); block->ssrc = htonl(rtp_session_get_recv_ssrc(session)); block->gmin = RTCP_XR_GMIN; // Fill RX config block->rx_config = 0; if (jbparams.adaptive) { block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_JBA_ADA; } else { block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_JBA_NON; } if (session->rtcp.xr_media_callbacks.plc != NULL) { switch (session->rtcp.xr_media_callbacks.plc(session->rtcp.xr_media_callbacks.userdata)) { default: case OrtpRtcpXrNoPlc: block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_PLC_UNS; break; case OrtpRtcpXrSilencePlc: block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_PLC_DIS; break; case OrtpRtcpXrEnhancedPlc: block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_PLC_ENH; break; } } else { block->rx_config |= RTCP_XR_VOIP_METRICS_CONFIG_PLC_UNS; } // Fill JB fields block->jb_nominal = htons((uint16_t)jbparams.nom_size); if (jbparams.adaptive) { block->jb_maximum = htons((session->rtp.jittctl.adapt_jitt_comp_ts * 1000) / session->rtp.jittctl.clock_rate); } else { block->jb_maximum = block->jb_nominal; } block->jb_abs_max = htons(65535); if (session->rtcp_xr_stats.rcv_count > 0) { expected_packets = session->rtcp_xr_stats.last_rcv_seq - session->rtcp_xr_stats.first_rcv_seq + 1; lost_packets = expected_packets - session->rtcp_xr_stats.rcv_count; block->loss_rate = calc_rate((double)lost_packets, (double)expected_packets); block->discard_rate = calc_rate((double)session->rtcp_xr_stats.discarded_count, (double)expected_packets); // TODO: fill burst_density, gap_density, burst_duration, gap_duration block->burst_density = 0; block->gap_density = 0; block->burst_duration = htons(0); block->gap_duration = htons(0); block->round_trip_delay = htons(int_rtt); // TODO: fill end_system_delay block->end_system_delay = htons(0); if (session->rtcp.xr_media_callbacks.signal_level != NULL) { block->signal_level = session->rtcp.xr_media_callbacks.signal_level(session->rtcp.xr_media_callbacks.userdata); } else { block->signal_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } if (session->rtcp.xr_media_callbacks.noise_level != NULL) { block->noise_level = session->rtcp.xr_media_callbacks.noise_level(session->rtcp.xr_media_callbacks.userdata); } else { block->noise_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } block->rerl = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; if (qi < 0) { block->r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } else { block->r_factor = (uint8_t)(qi * 20); } block->ext_r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; if (lq_qi < 0) { block->mos_lq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } else { block->mos_lq = (uint8_t)(lq_qi * 10); if (block->mos_lq < 10) block->mos_lq = 10; } if (qi < 0) { block->mos_cq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } else { block->mos_cq = (uint8_t)(qi * 10); if (block->mos_cq < 10) block->mos_cq = 10; } } else { block->loss_rate = 0; block->discard_rate = 0; block->burst_density = 0; block->gap_density = 0; block->burst_duration = htons(0); block->gap_duration = htons(0); block->round_trip_delay = htons(0); block->end_system_delay = htons(0); block->signal_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->noise_level = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->rerl = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->ext_r_factor = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->mos_lq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; block->mos_cq = ORTP_RTCP_XR_UNAVAILABLE_PARAMETER; } return sizeof(rtcp_xr_voip_metrics_report_block_t); }