From 90693a1969296f334e7fbdb7ceab9cbb035d7fa3 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Mon, 3 Apr 2017 14:53:20 -0400 Subject: [PATCH] TT#12800 refactor RCTP XR processing Change-Id: Ieb6279d866cae3e4f6b13c2755518c2bbb7e428c --- daemon/Makefile | 2 +- daemon/rtcp.c | 281 +++++++++++++++++++++++++++++++++++++++++++++-- daemon/rtcp_xr.c | 149 ------------------------- daemon/rtcp_xr.h | 200 --------------------------------- daemon/ssrc.h | 25 ++++- 5 files changed, 297 insertions(+), 360 deletions(-) delete mode 100644 daemon/rtcp_xr.c delete mode 100644 daemon/rtcp_xr.h diff --git a/daemon/Makefile b/daemon/Makefile index 2e7877ef6..6ed3654e5 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -38,7 +38,7 @@ include ../lib/lib.Makefile 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 ice.c socket.c \ - media_socket.c rtcp_xr.c homer.c recording.c statistics.c cdr.c ssrc.c + media_socket.c homer.c recording.c statistics.c cdr.c ssrc.c LIBSRCS= loglib.c auxlib.c rtplib.c OBJS= $(SRCS:.c=.o) $(LIBSRCS:.c=.o) diff --git a/daemon/rtcp.c b/daemon/rtcp.c index 239c3a79a..f31b2cb64 100644 --- a/daemon/rtcp.c +++ b/daemon/rtcp.c @@ -11,7 +11,6 @@ #include "log.h" #include "rtp.h" #include "crypto.h" -#include "rtcp_xr.h" #include "homer.h" #include "media_socket.h" #include "rtcplib.h" @@ -56,6 +55,14 @@ #define SDES_TYPE_NOTE 7 #define SDES_TYPE_PRIV 8 +/* 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 struct report_block { @@ -116,6 +123,89 @@ struct fb_packet { unsigned char information[0]; } __attribute__ ((packed)); +struct xr_report_block { + u_int8_t bt; /**< Block type. */ + u_int8_t specific; /**< Block specific data. */ + u_int16_t length; /**< Block length. */ +} __attribute__ ((packed)); + +struct xr_packet { + struct rtcp_packet rtcp; + struct xr_report_block report_blocks[0]; +} __attribute__ ((packed)); + +struct xr_rb_rr_time { + struct xr_report_block header; + u_int32_t ntp_sec; /**< NTP time, seconds part. */ + u_int32_t ntp_frac; /**< NTP time, fractions part. */ +} __attribute__ ((packed)); + +struct 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 */ +} __attribute__ ((packed)); + +struct xr_rb_dlrr { + struct xr_report_block header; + struct xr_rb_dlrr_item item; /**< Block contents, + variable length list */ +} __attribute__ ((packed)); + +struct xr_rb_stats { + struct xr_report_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 */ +} __attribute__ ((packed)); + +struct xr_rb_voip_metrics { + struct xr_report_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 */ +} __attribute__ ((packed)); + struct rtcp_chain_element { int type; unsigned int len; @@ -127,6 +217,7 @@ struct rtcp_chain_element { struct source_description_packet *sdes; struct bye_packet *bye; struct app_packet *app; + struct xr_packet *xr; } u; }; @@ -142,6 +233,7 @@ struct rtcp_process_ctx { union { struct ssrc_receiver_report rr; struct ssrc_sender_report sr; + struct ssrc_xr_voip_metrics xr_vm; } scratch; u_int32_t scratch_common_ssrc; @@ -157,11 +249,16 @@ struct rtcp_handler { void (*rr_list_start)(struct rtcp_process_ctx *, const struct rtcp_packet *); void (*rr)(struct rtcp_process_ctx *, const struct report_block *); void (*rr_list_end)(struct rtcp_process_ctx *); - void (*xr)(struct rtcp_process_ctx *, const struct rtcp_packet *, str *); + //void (*xr)(struct rtcp_process_ctx *, const struct rtcp_packet *, str *); void (*sdes_list_start)(struct rtcp_process_ctx *, const struct source_description_packet *); void (*sdes_item)(struct rtcp_process_ctx *, const struct sdes_chunk *, const struct sdes_item *, const char *); void (*sdes_list_end)(struct rtcp_process_ctx *); + void (*xr_rb)(struct rtcp_process_ctx *, const struct xr_report_block *); + void (*xr_dlrr)(struct rtcp_process_ctx *, const struct xr_rb_dlrr *); + void (*xr_stats)(struct rtcp_process_ctx *, const struct xr_rb_stats *); + void (*xr_rr_time)(struct rtcp_process_ctx *, const struct xr_rb_rr_time *); + void (*xr_voip_metrics)(struct rtcp_process_ctx *, const struct xr_rb_voip_metrics *); void (*finish)(struct rtcp_process_ctx *, struct call *, const endpoint_t *, const endpoint_t *, const struct timeval *); void (*destroy)(struct rtcp_process_ctx *); @@ -182,6 +279,7 @@ static void dummy_handler(); static void scratch_common(struct rtcp_process_ctx *, const struct rtcp_packet *); static void scratch_sr(struct rtcp_process_ctx *, const struct sender_report_packet *); static void scratch_rr(struct rtcp_process_ctx *, const struct report_block *); +static void scratch_xr_voip_metrics(struct rtcp_process_ctx *, const struct xr_rb_voip_metrics *); // MOS calculation / stats static void mos_sr(struct rtcp_process_ctx *, const struct sender_report_packet *); @@ -207,7 +305,11 @@ static void logging_common(struct rtcp_process_ctx *, const struct rtcp_packet * static void logging_sdes_list_start(struct rtcp_process_ctx *, const struct source_description_packet *); static void logging_sr(struct rtcp_process_ctx *, const struct sender_report_packet *); static void logging_rr(struct rtcp_process_ctx *, const struct report_block *); -static void logging_xr(struct rtcp_process_ctx *, const struct rtcp_packet *, str *); +static void logging_xr_rb(struct rtcp_process_ctx *, const struct xr_report_block *); +static void logging_xr_rr_time(struct rtcp_process_ctx *, const struct xr_rb_rr_time *); +static void logging_xr_dlrr(struct rtcp_process_ctx *, const struct xr_rb_dlrr *); +static void logging_xr_stats(struct rtcp_process_ctx *, const struct xr_rb_stats *); +static void logging_xr_voip_metrics(struct rtcp_process_ctx *, const struct xr_rb_voip_metrics *); static void logging_finish(struct rtcp_process_ctx *, struct call *, const endpoint_t *, const endpoint_t *, const struct timeval *); static void logging_destroy(struct rtcp_process_ctx *); @@ -218,6 +320,7 @@ static struct rtcp_handler scratch_handlers = { .common = scratch_common, .rr = scratch_rr, .sr = scratch_sr, + .xr_voip_metrics = scratch_xr_voip_metrics, }; static struct rtcp_handler mos_handlers = { .rr = mos_rr, @@ -230,7 +333,11 @@ static struct rtcp_handler log_handlers = { .sdes_list_start = logging_sdes_list_start, .sr = logging_sr, .rr = logging_rr, - .xr = logging_xr, + .xr_rb = logging_xr_rb, + .xr_rr_time = logging_xr_rr_time, + .xr_dlrr = logging_xr_dlrr, + .xr_stats = logging_xr_stats, + .xr_voip_metrics = logging_xr_voip_metrics, .finish = logging_finish, .destroy = logging_destroy, }; @@ -275,6 +382,7 @@ static struct rtcp_handler *all_handlers[] = { typedef int (*rtcp_handler_func)(struct rtcp_chain_element *, struct rtcp_process_ctx *); +typedef void (*xr_handler_func)(void *, struct rtcp_process_ctx *); static int rtcp_sr(struct rtcp_chain_element *, struct rtcp_process_ctx *); static int rtcp_rr(struct rtcp_chain_element *, struct rtcp_process_ctx *); @@ -282,6 +390,11 @@ static int rtcp_sdes(struct rtcp_chain_element *, struct rtcp_process_ctx *); static int rtcp_xr(struct rtcp_chain_element *, struct rtcp_process_ctx *); static int rtcp_generic(struct rtcp_chain_element *, struct rtcp_process_ctx *); +static void xr_rr_time(struct xr_rb_rr_time *, struct rtcp_process_ctx *); +static void xr_dlrr(struct xr_rb_dlrr *, struct rtcp_process_ctx *); +static void xr_stats(struct xr_rb_stats *, struct rtcp_process_ctx *); +static void xr_voip_metrics(struct xr_rb_voip_metrics *, struct rtcp_process_ctx *); + @@ -306,6 +419,19 @@ static const int min_packet_sizes[] = { [RTCP_PT_PSFB] = sizeof(struct fb_packet), }; +static const xr_handler_func xr_handler_funcs[] = { + [BT_RR_TIME] = (void *) xr_rr_time, + [BT_DLRR] = (void *) xr_dlrr, + [BT_STATS] = (void *) xr_stats, + [BT_VOIP_METRICS] = (void *) xr_voip_metrics, +}; +static const int min_xr_packet_sizes[] = { + [BT_RR_TIME] = sizeof(struct xr_rb_rr_time), + [BT_DLRR] = sizeof(struct xr_rb_dlrr), + [BT_STATS] = sizeof(struct xr_rb_stats), + [BT_VOIP_METRICS] = sizeof(struct xr_rb_voip_metrics), +}; + @@ -417,11 +543,52 @@ static int rtcp_sdes(struct rtcp_chain_element *el, struct rtcp_process_ctx *log return 0; } + + +static void xr_rr_time(struct xr_rb_rr_time *rb, struct rtcp_process_ctx *log_ctx) { + CAH(xr_rb, &rb->header); + CAH(xr_rr_time, rb); +} +static void xr_dlrr(struct xr_rb_dlrr *rb, struct rtcp_process_ctx *log_ctx) { + CAH(xr_rb, &rb->header); + CAH(xr_dlrr, rb); +} +static void xr_stats(struct xr_rb_stats *rb, struct rtcp_process_ctx *log_ctx) { + CAH(xr_rb, &rb->header); + CAH(xr_stats, rb); +} +static void xr_voip_metrics(struct xr_rb_voip_metrics *rb, struct rtcp_process_ctx *log_ctx) { + CAH(xr_rb, &rb->header); + CAH(xr_voip_metrics, rb); +} + static int rtcp_xr(struct rtcp_chain_element *el, struct rtcp_process_ctx *log_ctx) { CAH(common, el->u.rtcp_packet); str comp_s; - str_init_len(&comp_s, el->u.buf + sizeof(*el->u.rtcp_packet), el->len - sizeof(*el->u.rtcp_packet)); - CAH(xr, el->u.rtcp_packet, &comp_s); + str_init_len(&comp_s, el->u.buf + sizeof(el->u.xr->rtcp), el->len - sizeof(el->u.xr->rtcp)); + while (1) { + struct xr_report_block *rb = (void *) comp_s.s; + if (comp_s.len < sizeof(*rb)) + break; + unsigned int len = (ntohs(rb->length) + 1) << 2; + if (str_shift(&comp_s, len)) + break; + if (rb->bt >= G_N_ELEMENTS(xr_handler_funcs)) + goto next; + xr_handler_func hf = xr_handler_funcs[rb->bt]; + if (!hf) + goto next; + if (rb->bt < G_N_ELEMENTS(min_xr_packet_sizes) && len < min_xr_packet_sizes[rb->bt]) { + ilog(LOG_WARN, "Short RTCP XR block (type %u, %u < %i)", rb->bt, len, + min_xr_packet_sizes[rb->bt]); + goto next; + } + hf(rb, log_ctx); + +next: + ; + + } return 0; } @@ -604,7 +771,7 @@ static int rtcp_payload(struct rtcp_packet **out, str *p, const str *s) { rtcp = (void *) s->s; err = "invalid header version"; - if (rtcp->header.version != 2) /* version 2 */ + if (rtcp->header.version != 2) goto error; err = "invalid packet type"; if (rtcp->header.pt != RTCP_PT_SR @@ -735,6 +902,32 @@ static void scratch_sr(struct rtcp_process_ctx *ctx, const struct sender_report_ }; ctx->scratch.sr.ntp_ts = ntp_ts_to_double(ctx->scratch.sr.ntp_msw, ctx->scratch.sr.ntp_lsw); } +static void scratch_xr_voip_metrics(struct rtcp_process_ctx *ctx, const struct xr_rb_voip_metrics *vm) { + ctx->scratch.xr_vm = (struct ssrc_xr_voip_metrics) { + .ssrc = ntohl(vm->ssrc), + .loss_rate = vm->loss_rate, + .discard_rate = vm->discard_rate, + .burst_den = vm->burst_den, + .gap_den = vm->gap_den, + .burst_dur = ntohs(vm->burst_dur), + .gap_dur = ntohs(vm->gap_dur), + .rnd_trip_delay = ntohs(vm->rnd_trip_delay), + .end_sys_delay = ntohs(vm->end_sys_delay), + .signal_lvl = vm->signal_lvl, + .noise_lvl = vm->noise_lvl, + .rerl = vm->rerl, + .gmin = vm->gmin, + .r_factor = vm->r_factor, + .ext_r_factor = vm->ext_r_factor, + .mos_lq = vm->mos_lq, + .mos_cq = vm->mos_cq, + .rx_config = vm->rx_config, + .jb_nom = ntohs(vm->jb_nom), + .jb_max = ntohs(vm->jb_max), + .jb_abs_max = ntohs(vm->jb_abs_max), + + }; +} @@ -871,8 +1064,78 @@ static void logging_rr(struct rtcp_process_ctx *ctx, const struct report_block * ctx->scratch.rr.lsr, ctx->scratch.rr.dlsr); } -static void logging_xr(struct rtcp_process_ctx *ctx, const struct rtcp_packet *common, str *comp_s) { - pjmedia_rtcp_xr_rx_rtcp_xr(ctx->log, common, comp_s); +//static void logging_xr(struct rtcp_process_ctx *ctx, const struct rtcp_packet *common, str *comp_s) { + //pjmedia_rtcp_xr_rx_rtcp_xr(ctx->log, common, comp_s); +//} +static void logging_xr_rb(struct rtcp_process_ctx *ctx, const struct xr_report_block *rb_header) { + g_string_append_printf(ctx->log, "rb_header_blocktype=%u, rb_header_blockspecdata=%u, " \ + "rb_header_blocklength=%u, ", + rb_header->bt, + rb_header->specific, + ntohs(rb_header->length)); +} +static void logging_xr_rr_time(struct rtcp_process_ctx *ctx, const struct xr_rb_rr_time *rb_rr_time) { + g_string_append_printf(ctx->log, "rb_rr_time_ntp_sec=%u, rb_rr_time_ntp_frac=%u, ", + ntohl(rb_rr_time->ntp_sec), + ntohl(rb_rr_time->ntp_frac)); +} +static void logging_xr_dlrr(struct rtcp_process_ctx *ctx, const struct xr_rb_dlrr *rb_dlrr) { + g_string_append_printf(ctx->log, "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)); +} +static void logging_xr_stats(struct rtcp_process_ctx *ctx, const struct xr_rb_stats *rb_stats) { + g_string_append_printf(ctx->log, "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), + ntohs(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)); +} +static void logging_xr_voip_metrics(struct rtcp_process_ctx *ctx, const struct xr_rb_voip_metrics *rb_voip_mtc) { + g_string_append_printf(ctx->log, "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, ", + ctx->scratch.xr_vm.ssrc, + ctx->scratch.xr_vm.loss_rate, + ctx->scratch.xr_vm.discard_rate, + ctx->scratch.xr_vm.burst_den, + ctx->scratch.xr_vm.gap_den, + ctx->scratch.xr_vm.burst_dur, + ctx->scratch.xr_vm.gap_dur, + ctx->scratch.xr_vm.rnd_trip_delay, + ctx->scratch.xr_vm.end_sys_delay, + ctx->scratch.xr_vm.signal_lvl, + ctx->scratch.xr_vm.noise_lvl, + ctx->scratch.xr_vm.rerl, + ctx->scratch.xr_vm.gmin, + ctx->scratch.xr_vm.r_factor, + ctx->scratch.xr_vm.ext_r_factor, + ctx->scratch.xr_vm.mos_lq, + ctx->scratch.xr_vm.mos_cq, + ctx->scratch.xr_vm.rx_config, + ctx->scratch.xr_vm.jb_nom, + ctx->scratch.xr_vm.jb_max, + ctx->scratch.xr_vm.jb_abs_max); } static void logging_finish(struct rtcp_process_ctx *ctx, struct call *c, const endpoint_t *src, const endpoint_t *dst, const struct timeval *tv) diff --git a/daemon/rtcp_xr.c b/daemon/rtcp_xr.c deleted file mode 100644 index 650acab38..000000000 --- a/daemon/rtcp_xr.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * rtcp_xr.c - * - * Created on: Mar 29, 2015 - * Author: fmetz - */ -#include "rtcp_xr.h" -#include -#include -#include -#include "rtcplib.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_rb_header(GString *log, const pjmedia_rtcp_xr_rb_header *rb_header) { - g_string_append_printf(log, "rb_header_blocktype=%u, rb_header_blockspecdata=%u, rb_header_blocklength=%u, ", - rb_header->bt, - rb_header->specific, - ntohs(rb_header->length)); -} - -void print_rtcp_xr_rb_rr_time(GString *log, const pjmedia_rtcp_xr_rb_rr_time *rb_rr_time) { - print_rtcp_xr_rb_header(log, &rb_rr_time->header); - g_string_append_printf(log, "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(GString *log, const pjmedia_rtcp_xr_rb_dlrr *rb_dlrr) { - print_rtcp_xr_rb_header(log, &rb_dlrr->header); - g_string_append_printf(log, "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(GString *log, const pjmedia_rtcp_xr_rb_stats *rb_stats) { - print_rtcp_xr_rb_header(log, &rb_stats->header); - g_string_append_printf(log, "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), - ntohs(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(GString *log, const pjmedia_rtcp_xr_rb_voip_mtc *rb_voip_mtc) { - print_rtcp_xr_rb_header(log, &rb_voip_mtc->header); - g_string_append_printf(log, "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), - rb_voip_mtc->loss_rate, - rb_voip_mtc->discard_rate, - rb_voip_mtc->burst_den, - rb_voip_mtc->gap_den, - ntohs(rb_voip_mtc->burst_dur), - ntohs(rb_voip_mtc->gap_dur), - ntohs(rb_voip_mtc->rnd_trip_delay), - ntohs(rb_voip_mtc->end_sys_delay), - rb_voip_mtc->signal_lvl, - rb_voip_mtc->noise_lvl, - rb_voip_mtc->rerl, - rb_voip_mtc->gmin, - rb_voip_mtc->r_factor, - rb_voip_mtc->ext_r_factor, - rb_voip_mtc->mos_lq, - rb_voip_mtc->mos_cq, - rb_voip_mtc->rx_config, - ntohs(rb_voip_mtc->jb_nom), - ntohs(rb_voip_mtc->jb_max), - ntohs(rb_voip_mtc->jb_abs_max)); -} - -void pjmedia_rtcp_xr_rx_rtcp_xr(GString *log, const struct rtcp_packet *common, str *s) { - - const pjmedia_rtcp_xr_rb_rr_time *rb_rr_time; - const pjmedia_rtcp_xr_rb_dlrr *rb_dlrr; - const pjmedia_rtcp_xr_rb_stats *rb_stats; - const pjmedia_rtcp_xr_rb_voip_mtc *rb_voip_mtc; - const pjmedia_rtcp_xr_rb_header *rb_hdr; - unsigned pkt_len, rb_len; - - if (!log) - return; - - // packet length is guaranteed to be valid from upstream - - pkt_len = (ntohs(common->header.length) + 1) << 2; - - /* Parse report rpt_types */ - while (pkt_len >= sizeof(*rb_hdr)) - { - rb_hdr = (pjmedia_rtcp_xr_rb_header*) s->s; - rb_len = (ntohs((u_int16_t)rb_hdr->length) + 1) << 2; - if (str_shift(s, rb_len)) - break; - pkt_len -= rb_len; - - /* Just skip any block with length == 0 (no report content) */ - if (rb_len > 4) { - 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(log, rb_rr_time); - break; - case BT_DLRR: - rb_dlrr = (pjmedia_rtcp_xr_rb_dlrr*) rb_hdr; - print_rtcp_xr_rb_dlrr(log, rb_dlrr); - break; - case BT_STATS: - rb_stats = (pjmedia_rtcp_xr_rb_stats*) rb_hdr; - print_rtcp_xr_rb_stats(log, rb_stats); - break; - case BT_VOIP_METRICS: - rb_voip_mtc = (pjmedia_rtcp_xr_rb_voip_mtc*) rb_hdr; - print_rtcp_xr_rb_voip_mtc(log, rb_voip_mtc); - break; - default: - break; - } - } - } -} - diff --git a/daemon/rtcp_xr.h b/daemon/rtcp_xr.h deleted file mode 100644 index 1868086f3..000000000 --- a/daemon/rtcp_xr.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * rtcp_xr.h - * - * Created on: Mar 29, 2015 - * Author: fmetz - */ - -#ifndef RTCP_XR_H_ -#define RTCP_XR_H_ - -#include -#include -#include - -#include "str.h" -#include "rtcp.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; - - -/** - * 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(GString *, const struct rtcp_packet *common, str *s); - - -#pragma pack() - - -#endif /* RTCP_XR_H_ */ diff --git a/daemon/ssrc.h b/daemon/ssrc.h index 10977c387..c6707fd25 100644 --- a/daemon/ssrc.h +++ b/daemon/ssrc.h @@ -66,6 +66,30 @@ struct ssrc_receiver_report_item { struct ssrc_receiver_report report; }; +struct ssrc_xr_voip_metrics { + u_int32_t ssrc; + u_int8_t loss_rate; + u_int8_t discard_rate; + u_int8_t burst_den; + u_int8_t gap_den; + u_int16_t burst_dur; + u_int16_t gap_dur; + u_int16_t rnd_trip_delay; + u_int16_t end_sys_delay; + u_int8_t signal_lvl; + u_int8_t noise_lvl; + u_int8_t rerl; + u_int8_t gmin; + u_int8_t r_factor; + u_int8_t ext_r_factor; + u_int8_t mos_lq; + u_int8_t mos_cq; + u_int8_t rx_config; + u_int16_t jb_nom; + u_int16_t jb_max; + u_int16_t jb_abs_max; +}; + @@ -74,7 +98,6 @@ struct ssrc_hash *create_ssrc_hash(void); struct ssrc_entry *find_ssrc(u_int32_t, struct ssrc_hash *); // returns NULL if not found struct ssrc_entry *get_ssrc(u_int32_t, struct ssrc_hash * /* , int *created */); // creates new entry if not found -//void add_ssrc_entry(struct ssrc_entry *, struct ssrc_hash *); // XXX static //struct ssrc_entry *create_ssrc_entry(u_int32_t); struct ssrc_ctx *get_ssrc_ctx(u_int32_t, struct ssrc_hash *, enum ssrc_dir); // creates new entry if not found