mirror of https://github.com/sipwise/rtpengine.git
parent
d5db9d0f73
commit
070212ec3a
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* rtcp_xr.c
|
||||
*
|
||||
* Created on: Mar 29, 2015
|
||||
* Author: fmetz
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "rtcp_xr.h"
|
||||
|
||||
/* RTCP XR payload type */
|
||||
#define RTCP_XR 207
|
||||
|
||||
/* RTCP XR block types */
|
||||
#define BT_LOSS_RLE 1
|
||||
#define BT_DUP_RLE 2
|
||||
#define BT_RCPT_TIMES 3
|
||||
#define BT_RR_TIME 4
|
||||
#define BT_DLRR 5
|
||||
#define BT_STATS 6
|
||||
#define BT_VOIP_METRICS 7
|
||||
|
||||
|
||||
void print_rtcp_xr_common(char* cdrbufcur,pjmedia_rtcp_xr_pkt *rtcp_xr) {
|
||||
cdrbufcur += sprintf(cdrbufcur,"version=%u, padding=%u, count=%u, payloadtype=%u, length=%u, ssrc=%u, ",
|
||||
ntohl(rtcp_xr->common.version),
|
||||
ntohl(rtcp_xr->common.p),
|
||||
ntohl(rtcp_xr->common.count),
|
||||
ntohl(rtcp_xr->common.pt),
|
||||
ntohl(rtcp_xr->common.length),
|
||||
ntohl(rtcp_xr->common.ssrc));
|
||||
}
|
||||
|
||||
void print_rtcp_xr_rb_header(char* cdrbufcur,pjmedia_rtcp_xr_rb_header *rb_header) {
|
||||
cdrbufcur += sprintf(cdrbufcur,"rb_header_blocktype=%u, rb_header_blockspecdata=%u, rb_header_blocklength=%u, ",
|
||||
ntohl(rb_header->bt),
|
||||
ntohl(rb_header->specific),
|
||||
ntohl(rb_header->length));
|
||||
}
|
||||
|
||||
void print_rtcp_xr_rb_rr_time(char* cdrbufcur,pjmedia_rtcp_xr_rb_rr_time *rb_rr_time) {
|
||||
print_rtcp_xr_rb_header(cdrbufcur,&rb_rr_time->header);
|
||||
cdrbufcur += sprintf(cdrbufcur,"rb_rr_time_ntp_sec=%u, rb_rr_time_ntp_frac=%u, ",
|
||||
ntohl(rb_rr_time->ntp_sec),
|
||||
ntohl(rb_rr_time->ntp_frac));
|
||||
}
|
||||
|
||||
void print_rtcp_xr_rb_dlrr(char* cdrbufcur,pjmedia_rtcp_xr_rb_dlrr *rb_dlrr) {
|
||||
print_rtcp_xr_rb_header(cdrbufcur,&rb_dlrr->header);
|
||||
cdrbufcur += sprintf(cdrbufcur,"rb_dlrr_ssrc=%u, rb_dlrr_lrr=%u, rb_dlrr_dlrr=%u, ",
|
||||
ntohl(rb_dlrr->item.ssrc),
|
||||
ntohl(rb_dlrr->item.lrr),
|
||||
ntohl(rb_dlrr->item.dlrr));
|
||||
}
|
||||
|
||||
void print_rtcp_xr_rb_stats(char* cdrbufcur,pjmedia_rtcp_xr_rb_stats *rb_stats) {
|
||||
print_rtcp_xr_rb_header(cdrbufcur,&rb_stats->header);
|
||||
cdrbufcur += sprintf(cdrbufcur,"rb_stats_ssrc=%u, rb_stats_begin_seq=%u, rb_stats_end_seq=%u, rb_stats_lost_packets=%u, rb_stats_duplicate_packets=%u,"
|
||||
"rb_stats_jitter_min=%u, rb_stats_jitter_max=%u, rb_stats_jitter_mean=%u, rb_stats_jitter_deviation=%u,"
|
||||
"rb_stats_toh_min=%u, rb_stats_toh_max=%u, rb_stats_toh_mean=%u, rb_stats_toh_deviation=%u, ",
|
||||
ntohl(rb_stats->ssrc),
|
||||
ntohl(rb_stats->begin_seq),
|
||||
ntohl(rb_stats->end_seq),
|
||||
ntohl(rb_stats->lost),
|
||||
ntohl(rb_stats->dup),
|
||||
ntohl(rb_stats->jitter_min),
|
||||
ntohl(rb_stats->jitter_max),
|
||||
ntohl(rb_stats->jitter_mean),
|
||||
ntohl(rb_stats->jitter_dev),
|
||||
ntohl(rb_stats->toh_min),
|
||||
ntohl(rb_stats->toh_max),
|
||||
ntohl(rb_stats->toh_mean),
|
||||
ntohl(rb_stats->toh_dev));
|
||||
}
|
||||
|
||||
void print_rtcp_xr_rb_voip_mtc(char* cdrbufcur,pjmedia_rtcp_xr_rb_voip_mtc *rb_voip_mtc) {
|
||||
print_rtcp_xr_rb_header(cdrbufcur,&rb_voip_mtc->header);
|
||||
cdrbufcur += sprintf(cdrbufcur,"rb_voip_mtc_ssrc=%u, rb_voip_mtc_loss_rate=%u, rb_voip_mtc_discard_rate=%u, rb_voip_mtc_burst_den=%u, "
|
||||
"rb_voip_mtc_gap_den=%u, rb_voip_mtc_burst_dur=%u, rb_voip_mtc_gap_dur=%u, rb_voip_mtc_rnd_trip_delay=%u, "
|
||||
"rb_voip_mtc_end_sys_delay=%u, rb_voip_mtc_signal_lvl=%u, rb_voip_mtc_noise_lvl=%u, rb_voip_mtc_rerl=%u, "
|
||||
"rb_voip_mtc_gmin=%u, rb_voip_mtc_r_factor=%u, rb_voip_mtc_ext_r_factor=%u, rb_voip_mtc_mos_lq=%u, "
|
||||
"rb_voip_mtc_mos_cq=%u, rb_voip_mtc_rx_config=%u, rb_voip_mtc_jb_nom=%u, rb_voip_mtc_jb_max=%u, "
|
||||
"rb_voip_mtc_jb_abs_max=%u, ",
|
||||
ntohl(rb_voip_mtc->ssrc),
|
||||
ntohl(rb_voip_mtc->loss_rate),
|
||||
ntohl(rb_voip_mtc->discard_rate),
|
||||
ntohl(rb_voip_mtc->burst_den),
|
||||
ntohl(rb_voip_mtc->gap_den),
|
||||
ntohl(rb_voip_mtc->burst_dur),
|
||||
ntohl(rb_voip_mtc->gap_dur),
|
||||
ntohl(rb_voip_mtc->rnd_trip_delay),
|
||||
ntohl(rb_voip_mtc->end_sys_delay),
|
||||
ntohl(rb_voip_mtc->signal_lvl),
|
||||
ntohl(rb_voip_mtc->noise_lvl),
|
||||
ntohl(rb_voip_mtc->rerl),
|
||||
ntohl(rb_voip_mtc->gmin),
|
||||
ntohl(rb_voip_mtc->r_factor),
|
||||
ntohl(rb_voip_mtc->ext_r_factor),
|
||||
ntohl(rb_voip_mtc->mos_lq),
|
||||
ntohl(rb_voip_mtc->mos_cq),
|
||||
ntohl(rb_voip_mtc->rx_config),
|
||||
ntohl(rb_voip_mtc->jb_nom),
|
||||
ntohl(rb_voip_mtc->jb_max),
|
||||
ntohl(rb_voip_mtc->jb_abs_max));
|
||||
}
|
||||
|
||||
void pjmedia_rtcp_xr_rx_rtcp_xr(char* cdrbufcur, const void *pkt, size_t size) {
|
||||
|
||||
const pjmedia_rtcp_xr_pkt *rtcp_xr = (pjmedia_rtcp_xr_pkt*) pkt;
|
||||
const pjmedia_rtcp_xr_rb_rr_time *rb_rr_time = NULL;
|
||||
const pjmedia_rtcp_xr_rb_dlrr *rb_dlrr = NULL;
|
||||
const pjmedia_rtcp_xr_rb_stats *rb_stats = NULL;
|
||||
const pjmedia_rtcp_xr_rb_voip_mtc *rb_voip_mtc = NULL;
|
||||
const pjmedia_rtcp_xr_rb_header *rb_hdr = (pjmedia_rtcp_xr_rb_header*)
|
||||
rtcp_xr->buf;
|
||||
unsigned pkt_len, rb_len;
|
||||
|
||||
if (rtcp_xr->common.pt != RTCP_XR)
|
||||
return;
|
||||
|
||||
print_rtcp_xr_common(cdrbufcur,rtcp_xr);
|
||||
|
||||
pkt_len = ntohs((u_int16_t)rtcp_xr->common.length);
|
||||
|
||||
if ((pkt_len + 1) > (size / 4))
|
||||
return;
|
||||
|
||||
/* Parse report rpt_types */
|
||||
while ((int32_t*)rb_hdr < (int32_t*)pkt + pkt_len)
|
||||
{
|
||||
rb_len = ntohs((u_int16_t)rb_hdr->length);
|
||||
|
||||
/* Just skip any block with length == 0 (no report content) */
|
||||
if (rb_len) {
|
||||
switch (rb_hdr->bt) {
|
||||
case BT_RR_TIME:
|
||||
rb_rr_time = (pjmedia_rtcp_xr_rb_rr_time*) rb_hdr;
|
||||
print_rtcp_xr_rb_rr_time(cdrbufcur,rb_rr_time);
|
||||
break;
|
||||
case BT_DLRR:
|
||||
rb_dlrr = (pjmedia_rtcp_xr_rb_dlrr*) rb_hdr;
|
||||
print_rtcp_xr_rb_dlrr(cdrbufcur,rb_dlrr);
|
||||
break;
|
||||
case BT_STATS:
|
||||
rb_stats = (pjmedia_rtcp_xr_rb_stats*) rb_hdr;
|
||||
print_rtcp_xr_rb_stats(cdrbufcur,rb_stats);
|
||||
break;
|
||||
case BT_VOIP_METRICS:
|
||||
rb_voip_mtc = (pjmedia_rtcp_xr_rb_voip_mtc*) rb_hdr;
|
||||
print_rtcp_xr_rb_voip_mtc(cdrbufcur,rb_voip_mtc);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
rb_hdr = (pjmedia_rtcp_xr_rb_header*)
|
||||
((int32_t*)rb_hdr + rb_len + 1);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* rtcp_xr.h
|
||||
*
|
||||
* Created on: Mar 29, 2015
|
||||
* Author: fmetz
|
||||
*/
|
||||
|
||||
#ifndef RTCP_XR_H_
|
||||
#define RTCP_XR_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/**
|
||||
* @defgroup PJMED_RTCP_XR RTCP Extended Report (XR) - RFC 3611
|
||||
* @ingroup PJMEDIA_SESSION
|
||||
* @brief RTCP XR extension to RTCP session
|
||||
* @{
|
||||
*
|
||||
* PJMEDIA implements subsets of RTCP XR specification (RFC 3611) to monitor
|
||||
* the quality of the real-time media (audio/video) transmission.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enumeration of report types of RTCP XR. Useful for user to enable varying
|
||||
* combinations of RTCP XR report blocks.
|
||||
*/
|
||||
typedef enum {
|
||||
PJMEDIA_RTCP_XR_LOSS_RLE = (1 << 0),
|
||||
PJMEDIA_RTCP_XR_DUP_RLE = (1 << 1),
|
||||
PJMEDIA_RTCP_XR_RCPT_TIMES = (1 << 2),
|
||||
PJMEDIA_RTCP_XR_RR_TIME = (1 << 3),
|
||||
PJMEDIA_RTCP_XR_DLRR = (1 << 4),
|
||||
PJMEDIA_RTCP_XR_STATS = (1 << 5),
|
||||
PJMEDIA_RTCP_XR_VOIP_METRICS = (1 << 6)
|
||||
} pjmedia_rtcp_xr_type;
|
||||
|
||||
/**
|
||||
* Enumeration of info need to be updated manually to RTCP XR. Most info
|
||||
* could be updated automatically each time RTP received.
|
||||
*/
|
||||
typedef enum {
|
||||
PJMEDIA_RTCP_XR_INFO_SIGNAL_LVL = 1,
|
||||
PJMEDIA_RTCP_XR_INFO_NOISE_LVL = 2,
|
||||
PJMEDIA_RTCP_XR_INFO_RERL = 3,
|
||||
PJMEDIA_RTCP_XR_INFO_R_FACTOR = 4,
|
||||
PJMEDIA_RTCP_XR_INFO_MOS_LQ = 5,
|
||||
PJMEDIA_RTCP_XR_INFO_MOS_CQ = 6,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_PLC = 7,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_JBA = 8,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_JBR = 9,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_NOM = 10,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_MAX = 11,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX = 12
|
||||
} pjmedia_rtcp_xr_info;
|
||||
|
||||
/**
|
||||
* Enumeration of PLC types definitions for RTCP XR report.
|
||||
*/
|
||||
typedef enum {
|
||||
PJMEDIA_RTCP_XR_PLC_UNK = 0,
|
||||
PJMEDIA_RTCP_XR_PLC_DIS = 1,
|
||||
PJMEDIA_RTCP_XR_PLC_ENH = 2,
|
||||
PJMEDIA_RTCP_XR_PLC_STD = 3
|
||||
} pjmedia_rtcp_xr_plc_type;
|
||||
|
||||
/**
|
||||
* Enumeration of jitter buffer types definitions for RTCP XR report.
|
||||
*/
|
||||
typedef enum {
|
||||
PJMEDIA_RTCP_XR_JB_UNKNOWN = 0,
|
||||
PJMEDIA_RTCP_XR_JB_FIXED = 2,
|
||||
PJMEDIA_RTCP_XR_JB_ADAPTIVE = 3
|
||||
} pjmedia_rtcp_xr_jb_type;
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR Report Header.
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_header
|
||||
{
|
||||
u_int8_t bt; /**< Block type. */
|
||||
u_int8_t specific; /**< Block specific data. */
|
||||
u_int16_t length; /**< Block length. */
|
||||
} pjmedia_rtcp_xr_rb_header;
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR Receiver Reference Time Report Block.
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_rr_time
|
||||
{
|
||||
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
|
||||
u_int32_t ntp_sec; /**< NTP time, seconds part. */
|
||||
u_int32_t ntp_frac; /**< NTP time, fractions part. */
|
||||
} pjmedia_rtcp_xr_rb_rr_time;
|
||||
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR DLRR Report Sub-block
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_dlrr_item
|
||||
{
|
||||
u_int32_t ssrc; /**< receiver SSRC */
|
||||
u_int32_t lrr; /**< last receiver report */
|
||||
u_int32_t dlrr; /**< delay since last receiver
|
||||
report */
|
||||
} pjmedia_rtcp_xr_rb_dlrr_item;
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR DLRR Report Block
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_dlrr
|
||||
{
|
||||
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
|
||||
pjmedia_rtcp_xr_rb_dlrr_item item; /**< Block contents,
|
||||
variable length list */
|
||||
} pjmedia_rtcp_xr_rb_dlrr;
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR Statistics Summary Report Block
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_stats
|
||||
{
|
||||
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
|
||||
u_int32_t ssrc; /**< Receiver SSRC */
|
||||
u_int16_t begin_seq; /**< Begin RTP sequence reported */
|
||||
u_int16_t end_seq; /**< End RTP sequence reported */
|
||||
u_int32_t lost; /**< Number of packet lost in this
|
||||
interval */
|
||||
u_int32_t dup; /**< Number of duplicated packet in
|
||||
this interval */
|
||||
u_int32_t jitter_min; /**< Minimum jitter in this interval */
|
||||
u_int32_t jitter_max; /**< Maximum jitter in this interval */
|
||||
u_int32_t jitter_mean; /**< Average jitter in this interval */
|
||||
u_int32_t jitter_dev; /**< Jitter deviation in this
|
||||
interval */
|
||||
u_int32_t toh_min:8; /**< Minimum ToH in this interval */
|
||||
u_int32_t toh_max:8; /**< Maximum ToH in this interval */
|
||||
u_int32_t toh_mean:8; /**< Average ToH in this interval */
|
||||
u_int32_t toh_dev:8; /**< ToH deviation in this interval */
|
||||
} pjmedia_rtcp_xr_rb_stats;
|
||||
|
||||
/**
|
||||
* This type declares RTCP XR VoIP Metrics Report Block
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_rb_voip_mtc
|
||||
{
|
||||
pjmedia_rtcp_xr_rb_header header; /**< Block header. */
|
||||
u_int32_t ssrc; /**< Receiver SSRC */
|
||||
u_int8_t loss_rate; /**< Packet loss rate */
|
||||
u_int8_t discard_rate; /**< Packet discarded rate */
|
||||
u_int8_t burst_den; /**< Burst density */
|
||||
u_int8_t gap_den; /**< Gap density */
|
||||
u_int16_t burst_dur; /**< Burst duration */
|
||||
u_int16_t gap_dur; /**< Gap duration */
|
||||
u_int16_t rnd_trip_delay;/**< Round trip delay */
|
||||
u_int16_t end_sys_delay; /**< End system delay */
|
||||
u_int8_t signal_lvl; /**< Signal level */
|
||||
u_int8_t noise_lvl; /**< Noise level */
|
||||
u_int8_t rerl; /**< Residual Echo Return Loss */
|
||||
u_int8_t gmin; /**< The gap threshold */
|
||||
u_int8_t r_factor; /**< Voice quality metric carried
|
||||
over this RTP session */
|
||||
u_int8_t ext_r_factor; /**< Voice quality metric carried
|
||||
outside of this RTP session*/
|
||||
u_int8_t mos_lq; /**< Mean Opinion Score for
|
||||
Listening Quality */
|
||||
u_int8_t mos_cq; /**< Mean Opinion Score for
|
||||
Conversation Quality */
|
||||
u_int8_t rx_config; /**< Receiver configuration */
|
||||
u_int8_t reserved2; /**< Not used */
|
||||
u_int16_t jb_nom; /**< Current delay by jitter
|
||||
buffer */
|
||||
u_int16_t jb_max; /**< Maximum delay by jitter
|
||||
buffer */
|
||||
u_int16_t jb_abs_max; /**< Maximum possible delay by
|
||||
jitter buffer */
|
||||
} pjmedia_rtcp_xr_rb_voip_mtc;
|
||||
|
||||
|
||||
/**
|
||||
* Constant of RTCP-XR content size.
|
||||
*/
|
||||
#define PJMEDIA_RTCP_XR_BUF_SIZE \
|
||||
sizeof(pjmedia_rtcp_xr_rb_rr_time) + \
|
||||
sizeof(pjmedia_rtcp_xr_rb_dlrr) + \
|
||||
sizeof(pjmedia_rtcp_xr_rb_stats) + \
|
||||
sizeof(pjmedia_rtcp_xr_rb_voip_mtc)
|
||||
|
||||
|
||||
/**
|
||||
* This structure declares RTCP XR (Extended Report) packet.
|
||||
*/
|
||||
typedef struct pjmedia_rtcp_xr_pkt
|
||||
{
|
||||
struct {
|
||||
#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
|
||||
unsigned version:2; /**< packet type */
|
||||
unsigned p:1; /**< padding flag */
|
||||
unsigned count:5; /**< varies by payload type */
|
||||
unsigned pt:8; /**< payload type */
|
||||
#else
|
||||
unsigned count:5; /**< varies by payload type */
|
||||
unsigned p:1; /**< padding flag */
|
||||
unsigned version:2; /**< packet type */
|
||||
unsigned pt:8; /**< payload type */
|
||||
#endif
|
||||
unsigned length:16; /**< packet length */
|
||||
u_int32_t ssrc; /**< SSRC identification */
|
||||
} common;
|
||||
|
||||
int8_t buf[PJMEDIA_RTCP_XR_BUF_SIZE];
|
||||
/**< Content buffer */
|
||||
} pjmedia_rtcp_xr_pkt;
|
||||
|
||||
|
||||
/**
|
||||
* This function is called internally by RTCP session when it receives
|
||||
* incoming RTCP XR packets.
|
||||
*
|
||||
* @param rtcp_pkt The received RTCP XR packet.
|
||||
* @param size Size of the incoming packet.
|
||||
*/
|
||||
void pjmedia_rtcp_xr_rx_rtcp_xr( char* cdrbufcur, const void *rtcp_pkt, size_t size);
|
||||
|
||||
|
||||
#endif /* RTCP_XR_H_ */
|
Loading…
Reference in new issue