Added RTCP parsing and option to log that information

pull/101/head
Frederic-Philippe Metz 10 years ago
parent d5db9d0f73
commit 070212ec3a

@ -178,6 +178,7 @@ option and which are reproduced below:
-L, --log-level=INT Mask log priorities above this level
--log-facility=daemon|local0|... Syslog facility to use for logging
--log-facility-cdr=local0|... Syslog facility to use for logging CDRs
--log-facility-rtcp=local0|... Syslog facility to use for logging RTCP data (take care of traffic amount)
-E, --log-stderr Log on stderr instead of syslog
-x, --xmlrpc-format=INT XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only
--num-threads=INT Number of worker threads to create
@ -322,6 +323,11 @@ The options are described in more detail below.
Same as --log-facility with the difference that only CDRs are written to this log facility.
* --log-facilty-rtcp=daemon|local0|...|local7|...
Same as --log-facility with the difference that only RTCP data is written to this log facility.
Be careful with this parameter since there may be a lot of information written to it.
* -E, --log-stderr
Log to stderr instead of syslog. Only useful in combination with `--foreground`.

@ -63,7 +63,7 @@ endif
SRCS= main.c kernel.c poller.c aux.c control_tcp.c streambuf.c call.c control_udp.c redis.c \
bencode.c cookie_cache.c udp_listener.c control_ng.c sdp.c str.c stun.c rtcp.c \
crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c graphite.c
crypto.c rtp.c call_interfaces.c dtls.c log.c cli.c graphite.c rtcp_xr.c
OBJS= $(SRCS:.c=.o)

@ -672,6 +672,9 @@ loop_ok:
if (!sink && PS_ISSET(stream, RTCP)) {
sink = stream->rtcp_sink;
rtcp = 1;
if (_log_facility_rtcp) {
parse_and_log_rtcp_report(sfd, s->s, s->len);
}
}
else if (stream->rtcp_sink) {
muxed_rtcp = rtcp_demux(s, media);

@ -58,6 +58,7 @@ static const char* const prio_str[] = {
gboolean _log_stderr = 0;
int _log_facility = LOG_DAEMON;
int _log_facility_cdr = 0;
int _log_facility_rtcp = 0;
static GHashTable *__log_limiter;
@ -176,6 +177,14 @@ void cdrlog(const char* cdrbuffer) {
setlogmask(previous);
}
void rtcplog(const char* cdrbuffer) {
int previous;
int mask = LOG_MASK (LOG_INFO);
previous = setlogmask(mask);
syslog(LOG_INFO | _log_facility_rtcp, "%s", cdrbuffer);
setlogmask(previous);
}
void log_init() {
mutex_init(&__log_limiter_lock);
__log_limiter = g_hash_table_new(g_str_hash, g_str_equal);

@ -23,6 +23,7 @@ struct log_info {
extern gboolean _log_stderr;
extern int _log_facility;
extern int _log_facility_cdr;
extern int _log_facility_rtcp;
typedef struct _fac_code {
@ -48,6 +49,7 @@ void log_init(void);
void ilog(int prio, const char *fmt, ...)__attribute__ ((format (printf, 2, 3)));
void cdrlog(const char* cdrbuffer);
void rtcplog(const char* cdrbuffer);
#include "obj.h"

@ -259,7 +259,8 @@ static void options(int *argc, char ***argv) {
char *graphitep = NULL;
char *redisps = NULL;
char *log_facility_s = NULL;
char *log_facility_cdr_s = NULL;
char *log_facility_cdr_s = NULL;
char *log_facility_rtcp_s = NULL;
int version = 0;
int sip_source = 0;
@ -287,6 +288,7 @@ static void options(int *argc, char ***argv) {
{ "log-level", 'L', 0, G_OPTION_ARG_INT, (void *)&log_level,"Mask log priorities above this level","INT" },
{ "log-facility",0, 0, G_OPTION_ARG_STRING, &log_facility_s, "Syslog facility to use for logging", "daemon|local0|...|local7"},
{ "log-facility-cdr",0, 0, G_OPTION_ARG_STRING, &log_facility_cdr_s, "Syslog facility to use for logging CDRs", "daemon|local0|...|local7"},
{ "log-facility-rtcp",0, 0, G_OPTION_ARG_STRING, &log_facility_rtcp_s, "Syslog facility to use for logging RTCP", "daemon|local0|...|local7"},
{ "log-stderr", 'E', 0, G_OPTION_ARG_NONE, &_log_stderr, "Log on stderr instead of syslog", NULL },
{ "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &xmlrpc_fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only", "INT" },
{ "num-threads", 0, 0, G_OPTION_ARG_INT, &num_threads, "Number of worker threads to create", "INT" },
@ -369,12 +371,19 @@ static void options(int *argc, char ***argv) {
}
}
if (log_facility_cdr_s) {
if (!parse_log_facility(log_facility_cdr_s, &_log_facility_cdr)) {
print_available_log_facilities();
die ("Invalid log facility for CDR '%s' (--log-facility-cdr)\n", log_facility_cdr_s);
}
}
if (log_facility_cdr_s) {
if (!parse_log_facility(log_facility_cdr_s, &_log_facility_cdr)) {
print_available_log_facilities();
die ("Invalid log facility for CDR '%s' (--log-facility-cdr)\n", log_facility_cdr_s);
}
}
if (log_facility_rtcp_s) {
if (!parse_log_facility(log_facility_rtcp_s, &_log_facility_rtcp)) {
print_available_log_facilities();
die ("Invalid log facility for RTCP '%s' (--log-facility-rtcp)\n", log_facility_rtcp_s);
}
}
if (_log_stderr) {
write_log = log_to_stderr;

@ -11,6 +11,7 @@
#include "log.h"
#include "rtp.h"
#include "crypto.h"
#include "rtcp_xr.h"
@ -26,9 +27,6 @@
#define SRTCP_R_LENGTH 6
#endif
#define RTCP_PT_SR 200 /* sender report */
#define RTCP_PT_RR 201 /* receiver report */
#define RTCP_PT_SDES 202 /* source description */
@ -36,6 +34,7 @@
#define RTCP_PT_APP 204 /* application specific */
#define RTCP_PT_RTPFB 205 /* transport layer feedback message (RTP/AVPF) */
#define RTCP_PT_PSFB 206 /* payload-specific feedback message (RTP/AVPF) */
#define RTCP_PT_XR 207
#define SDES_TYPE_END 0
#define SDES_TYPE_CNAME 1
@ -481,3 +480,73 @@ int rtcp_demux_is_rtcp(const str *s) {
return 0;
return 1;
}
void print_rtcp_common(char** cdrbufcur, const pjmedia_rtcp_common *common) {
*cdrbufcur += sprintf(*cdrbufcur,"version=%u, padding=%u, count=%u, payloadtype=%u, length=%u, ssrc=%u, ",
ntohl(common->version),
ntohl(common->p),
ntohl(common->count),
ntohl(common->pt),
ntohl(common->length),
ntohl(common->ssrc));
}
void print_rtcp_sr(char** cdrbufcur, const pjmedia_rtcp_sr* sr) {
*cdrbufcur += sprintf(*cdrbufcur,"ntp_sec=%u, ntp_fractions=%u, rtp_ts=%u, sender_packets=%u, sender_bytes=%u, ",
ntohl(sr->ntp_sec),
ntohl(sr->ntp_frac),
ntohl(sr->rtp_ts),
ntohl(sr->sender_pcount),
ntohl(sr->sender_bcount));
}
void print_rtcp_rr(char** cdrbufcur, const pjmedia_rtcp_rr* rr) {
/* Get packet loss */
u_int32_t packet_loss=0;
packet_loss = (rr->total_lost_2 << 16) +
(rr->total_lost_1 << 8) +
rr->total_lost_0;
*cdrbufcur += sprintf(*cdrbufcur,"ssrc=%u, fraction_lost=%u, packet_loss=%u, last_seq=%u, jitter=%u, last_sr=%u, delay_since_last_sr=%u, ",
ntohl(rr->ssrc),
ntohl(rr->fract_lost),
ntohl(packet_loss),
ntohl(rr->last_seq),
ntohl(rr->jitter),
ntohl(rr->lsr),
ntohl(rr->dlsr));
}
void parse_and_log_rtcp_report(struct stream_fd *sfd, const void *pkt, long size) {
static const int CDRBUFLENGTH = 1024*1024*1; // 1 MB
char cdrbuffer[CDRBUFLENGTH]; memset(&cdrbuffer,0,CDRBUFLENGTH);
char* cdrbufcur = cdrbuffer;
pjmedia_rtcp_common *common = (pjmedia_rtcp_common*) pkt;
const pjmedia_rtcp_rr *rr = NULL;
const pjmedia_rtcp_sr *sr = NULL;
cdrbufcur += sprintf(cdrbufcur,"[%s] ",sfd->stream->call->callid);
print_rtcp_common(&cdrbufcur,common);
/* Parse RTCP */
if (common->pt == RTCP_PT_SR) {
sr = (pjmedia_rtcp_sr*) (((char*)pkt) + sizeof(pjmedia_rtcp_common));
print_rtcp_sr(&cdrbufcur,sr);
if (common->count > 0 && size >= (sizeof(pjmedia_rtcp_sr_pkt))) {
rr = (pjmedia_rtcp_rr*)(((char*)pkt) + (sizeof(pjmedia_rtcp_common)
+ sizeof(pjmedia_rtcp_sr)));
print_rtcp_rr(&cdrbufcur,rr);
}
} else if (common->pt == RTCP_PT_RR && common->count > 0) {
rr = (pjmedia_rtcp_rr*)(((char*)pkt) + sizeof(pjmedia_rtcp_common));
print_rtcp_rr(&cdrbufcur,rr);
} else if (common->pt == RTCP_PT_XR) {
pjmedia_rtcp_xr_rx_rtcp_xr(&cdrbufcur, pkt, size);
}
rtcplog(cdrbuffer);
}

@ -2,6 +2,7 @@
#define _RTCP_H_
#include "str.h"
#include "call.h"
struct crypto_context;
@ -19,6 +20,83 @@ struct rtcp_packet {
u_int32_t ssrc;
} __attribute__ ((packed));
/**
* RTCP sender report.
*/
typedef struct pjmedia_rtcp_sr
{
u_int32_t ntp_sec; /**< NTP time, seconds part. */
u_int32_t ntp_frac; /**< NTP time, fractions part. */
u_int32_t rtp_ts; /**< RTP timestamp. */
u_int32_t sender_pcount; /**< Sender packet cound. */
u_int32_t sender_bcount; /**< Sender octet/bytes count. */
} pjmedia_rtcp_sr;
/**
* RTCP receiver report.
*/
typedef struct pjmedia_rtcp_rr
{
u_int32_t ssrc; /**< SSRC identification. */
#if defined(PJ_IS_BIG_ENDIAN) && PJ_IS_BIG_ENDIAN!=0
u_int32_t fract_lost:8; /**< Fraction lost. */
u_int32_t total_lost_2:8; /**< Total lost, bit 16-23. */
u_int32_t total_lost_1:8; /**< Total lost, bit 8-15. */
u_int32_t total_lost_0:8; /**< Total lost, bit 0-7. */
#else
u_int32_t fract_lost:8; /**< Fraction lost. */
u_int32_t total_lost_2:8; /**< Total lost, bit 0-7. */
u_int32_t total_lost_1:8; /**< Total lost, bit 8-15. */
u_int32_t total_lost_0:8; /**< Total lost, bit 16-23. */
#endif
u_int32_t last_seq; /**< Last sequence number. */
u_int32_t jitter; /**< Jitter. */
u_int32_t lsr; /**< Last SR. */
u_int32_t dlsr; /**< Delay since last SR. */
} pjmedia_rtcp_rr;
/**
* RTCP common header.
*/
typedef struct pjmedia_rtcp_common
{
#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 */
} pjmedia_rtcp_common;
/**
* This structure declares default RTCP packet (SR) that is sent by pjmedia.
* Incoming RTCP packet may have different format, and must be parsed
* manually by application.
*/
typedef struct pjmedia_rtcp_sr_pkt
{
pjmedia_rtcp_common common; /**< Common header. */
pjmedia_rtcp_sr sr; /**< Sender report. */
pjmedia_rtcp_rr rr; /**< variable-length list */
} pjmedia_rtcp_sr_pkt;
/**
* This structure declares RTCP RR (Receiver Report) packet.
*/
typedef struct pjmedia_rtcp_rr_pkt
{
pjmedia_rtcp_common common; /**< Common header. */
pjmedia_rtcp_rr rr; /**< variable-length list */
} pjmedia_rtcp_rr_pkt;
int rtcp_avpf2avp(str *);
@ -27,6 +105,6 @@ int rtcp_savp2avp(str *, struct crypto_context *);
int rtcp_demux_is_rtcp(const str *);
void parse_and_log_rtcp_report(struct stream_fd *sfd, const void *pkt, long size);
#endif

@ -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_ */

@ -21,6 +21,7 @@ TABLE=0
# LOG_LEVEL=6
# LOG_FACILITY=daemon
# LOG_FACILITY_CDR=daemon
# LOG_FACILITY_RTCP=daemon
# NUM_THREADS=5
# DELETE_DELAY=30
# GRAPHITE=9006

@ -70,6 +70,7 @@ OPTIONS="$OPTIONS --table=$TABLE"
[ -z "$LOG_LEVEL" ] || OPTIONS="$OPTIONS --log-level=$LOG_LEVEL"
[ -z "$LOG_FACILITY" ] || OPTIONS="$OPTIONS --log-facility=$LOG_FACILITY"
[ -z "$LOG_FACILITY_CDR" ] || OPTIONS="$OPTIONS --log-facility-cdr=$LOG_FACILITY_CDR"
[ -z "$LOG_FACILITY_RTCP" ] || OPTIONS="$OPTIONS --log-facility-rtcp=$LOG_FACILITY_RTCP"
[ -z "$NUM_THREADS" ] || OPTIONS="$OPTIONS --num-threads=$NUM_THREADS"
[ -z "$DELETE_DELAY" ] || OPTIONS="$OPTIONS --delete-delay=$DELETE_DELAY"
[ -z "$GRAPHITE" ] || OPTIONS="$OPTIONS --graphite=$GRAPHITE"

@ -157,6 +157,11 @@ build_opts() {
then
OPTS+=" --log-facility-cdr=$LOG_FACILITY_CDR"
fi
if [[ -n "$LOG_FACILITY_RTCP" ]]
then
OPTS+=" --log-facility-rtcp=$LOG_FACILITY_RTCP"
fi
}
start() {

Loading…
Cancel
Save