|
|
|
|
@ -64,7 +64,8 @@ static void call_ng_flags_list(const ng_parser_t *, parser_arg list,
|
|
|
|
|
void (*item_callback)(const ng_parser_t *, parser_arg, helper_arg),
|
|
|
|
|
helper_arg);
|
|
|
|
|
static void call_ng_flags_esc_str_list(str *s, unsigned int, helper_arg);
|
|
|
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, const struct ssrc_hash *ht);
|
|
|
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, parser_arg list,
|
|
|
|
|
const struct ssrc_hash *ht);
|
|
|
|
|
static str *str_dup_escape(const str *s);
|
|
|
|
|
static void call_set_dtmf_block(call_t *call, struct call_monologue *monologue, sdp_ng_flags *flags);
|
|
|
|
|
|
|
|
|
|
@ -2748,27 +2749,6 @@ static void ng_stats_endpoint(const ng_parser_t *parser, parser_arg dict, const
|
|
|
|
|
parser->dict_add_int(dict, "port", ep->port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ng_stats_stream_ssrc(const ng_parser_t *parser, parser_arg dict,
|
|
|
|
|
struct ssrc_entry_call *const ssrcs[RTPE_NUM_SSRC_TRACKING],
|
|
|
|
|
const char *label)
|
|
|
|
|
{
|
|
|
|
|
parser_arg list = parser->dict_add_list(dict, label);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < RTPE_NUM_SSRC_TRACKING; i++) {
|
|
|
|
|
struct ssrc_entry_call *c = ssrcs[i];
|
|
|
|
|
if (!c)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
parser_arg ssrc = parser->list_add_dict(list);
|
|
|
|
|
|
|
|
|
|
parser->dict_add_int(ssrc, "SSRC", ssrcs[i]->h.ssrc);
|
|
|
|
|
parser->dict_add_int(ssrc, "bytes", atomic64_get_na(&c->stats->bytes));
|
|
|
|
|
parser->dict_add_int(ssrc, "packets", atomic64_get_na(&c->stats->packets));
|
|
|
|
|
parser->dict_add_int(ssrc, "last RTP timestamp", atomic_get_na(&c->stats->timestamp));
|
|
|
|
|
parser->dict_add_int(ssrc, "last RTP seq", atomic_get_na(&c->stats->ext_seq));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define BF_PS(k, f) if (PS_ISSET(ps, f)) parser->list_add_string(flags, k)
|
|
|
|
|
|
|
|
|
|
static void ng_stats_stream(ng_command_ctx_t *ctx, parser_arg list, const struct packet_stream *ps,
|
|
|
|
|
@ -2800,6 +2780,10 @@ static void ng_stats_stream(ng_command_ctx_t *ctx, parser_arg list, const struct
|
|
|
|
|
parser->dict_add_int(dict, "last kernel packet", atomic64_get_na(&ps->stats_in->last_packet_us) / 1000000L);
|
|
|
|
|
parser->dict_add_int(dict, "last user packet", atomic64_get_na(&ps->last_packet_us) / 1000000L);
|
|
|
|
|
|
|
|
|
|
__auto_type se = call_get_first_ssrc(&ps->media->ssrc_hash_in);
|
|
|
|
|
if (se)
|
|
|
|
|
parser->dict_add_int(dict, "SSRC", se->h.ssrc);
|
|
|
|
|
|
|
|
|
|
flags = parser->dict_add_list(dict, "flags");
|
|
|
|
|
|
|
|
|
|
BF_PS("RTP", RTP);
|
|
|
|
|
@ -2814,9 +2798,6 @@ static void ng_stats_stream(ng_command_ctx_t *ctx, parser_arg list, const struct
|
|
|
|
|
BF_PS("media handover", MEDIA_HANDOVER);
|
|
|
|
|
BF_PS("ICE", ICE);
|
|
|
|
|
|
|
|
|
|
ng_stats_stream_ssrc(parser, dict, ps->ssrc_in, "ingress SSRCs");
|
|
|
|
|
ng_stats_stream_ssrc(parser, dict, ps->ssrc_out, "egress SSRCs");
|
|
|
|
|
|
|
|
|
|
stats:
|
|
|
|
|
if (totals->last_packet_us < packet_stream_last_packet(ps))
|
|
|
|
|
totals->last_packet_us = packet_stream_last_packet(ps);
|
|
|
|
|
@ -2888,7 +2869,8 @@ static void ng_stats_media(ng_command_ctx_t *ctx, parser_arg list, const struct
|
|
|
|
|
BF_M("transcoding", TRANSCODING);
|
|
|
|
|
BF_M("block egress", BLOCK_EGRESS);
|
|
|
|
|
|
|
|
|
|
ng_stats_ssrc(parser, ssrc, &m->ssrc_hash_in); // XXX out
|
|
|
|
|
ng_stats_ssrc(parser, ssrc, parser->dict_add_list(dict, "ingress SSRCs"), &m->ssrc_hash_in);
|
|
|
|
|
ng_stats_ssrc(parser, NULL, parser->dict_add_list(dict, "egress SSRCs"), &m->ssrc_hash_out);
|
|
|
|
|
|
|
|
|
|
stats:
|
|
|
|
|
for (auto_iter(l, m->streams.head); l; l = l->next) {
|
|
|
|
|
@ -3030,45 +3012,61 @@ static void ng_stats_ssrc_mos_entry_dict_avg(const ng_parser_t *parser, parser_a
|
|
|
|
|
parser->dict_add_int(subent, "samples", div);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, const struct ssrc_hash *ht) {
|
|
|
|
|
static void ng_stats_ssrc_1(const ng_parser_t *parser, parser_arg ent, struct ssrc_entry_call *se) {
|
|
|
|
|
parser->dict_add_int(ent, "bytes", atomic64_get_na(&se->stats->bytes));
|
|
|
|
|
parser->dict_add_int(ent, "packets", atomic64_get_na(&se->stats->packets));
|
|
|
|
|
parser->dict_add_int(ent, "last RTP timestamp", atomic_get_na(&se->stats->timestamp));
|
|
|
|
|
parser->dict_add_int(ent, "last RTP seq", atomic_get_na(&se->stats->ext_seq));
|
|
|
|
|
|
|
|
|
|
parser->dict_add_int(ent, "cumulative loss", se->packets_lost);
|
|
|
|
|
|
|
|
|
|
int mos_samples = se->stats_blocks.length - se->no_mos_count;
|
|
|
|
|
if (mos_samples < 1) mos_samples = 1;
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict_avg(parser, ent, "average MOS", &se->average_mos, mos_samples);
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict(parser, ent, "lowest MOS", se->lowest_mos);
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict(parser, ent, "highest MOS", se->highest_mos);
|
|
|
|
|
|
|
|
|
|
parser_arg progdict = parser->dict_add_dict(ent, "MOS progression");
|
|
|
|
|
// aim for about 10 entries to the list
|
|
|
|
|
GList *listent = se->stats_blocks.head;
|
|
|
|
|
struct ssrc_stats_block *sb = listent->data;
|
|
|
|
|
int64_t interval
|
|
|
|
|
= ((struct ssrc_stats_block *) se->stats_blocks.tail->data)->reported
|
|
|
|
|
- sb->reported;
|
|
|
|
|
interval /= 10;
|
|
|
|
|
parser->dict_add_int(progdict, "interval", interval / 1000000L);
|
|
|
|
|
int64_t next_step = sb->reported;
|
|
|
|
|
parser_arg entlist = parser->dict_add_list(progdict, "entries");
|
|
|
|
|
|
|
|
|
|
for (; listent; listent = listent->next) {
|
|
|
|
|
sb = listent->data;
|
|
|
|
|
if (sb->reported < next_step)
|
|
|
|
|
continue;
|
|
|
|
|
next_step += interval;
|
|
|
|
|
parser_arg cent = parser->list_add_dict(entlist);
|
|
|
|
|
ng_stats_ssrc_mos_entry(parser, cent, sb);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ng_stats_ssrc(const ng_parser_t *parser, parser_arg dict, parser_arg list,
|
|
|
|
|
const struct ssrc_hash *ht)
|
|
|
|
|
{
|
|
|
|
|
for (GList *l = ht->nq.head; l; l = l->next) {
|
|
|
|
|
struct ssrc_entry_call *se = l->data;
|
|
|
|
|
char tmp[12];
|
|
|
|
|
snprintf(tmp, sizeof(tmp), "%" PRIu32, se->h.ssrc);
|
|
|
|
|
if (parser->dict_contains(dict, tmp))
|
|
|
|
|
continue;
|
|
|
|
|
if (!se->stats_blocks.length || !se->lowest_mos || !se->highest_mos)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
parser_arg ent = parser->dict_add_dict_dup(dict, tmp);
|
|
|
|
|
|
|
|
|
|
parser->dict_add_int(ent, "cumulative loss", se->packets_lost);
|
|
|
|
|
|
|
|
|
|
int mos_samples = se->stats_blocks.length - se->no_mos_count;
|
|
|
|
|
if (mos_samples < 1) mos_samples = 1;
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict_avg(parser, ent, "average MOS", &se->average_mos, mos_samples);
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict(parser, ent, "lowest MOS", se->lowest_mos);
|
|
|
|
|
ng_stats_ssrc_mos_entry_dict(parser, ent, "highest MOS", se->highest_mos);
|
|
|
|
|
|
|
|
|
|
parser_arg progdict = parser->dict_add_dict(ent, "MOS progression");
|
|
|
|
|
// aim for about 10 entries to the list
|
|
|
|
|
GList *listent = se->stats_blocks.head;
|
|
|
|
|
struct ssrc_stats_block *sb = listent->data;
|
|
|
|
|
int64_t interval
|
|
|
|
|
= ((struct ssrc_stats_block *) se->stats_blocks.tail->data)->reported
|
|
|
|
|
- sb->reported;
|
|
|
|
|
interval /= 10;
|
|
|
|
|
parser->dict_add_int(progdict, "interval", interval / 1000000L);
|
|
|
|
|
int64_t next_step = sb->reported;
|
|
|
|
|
parser_arg entlist = parser->dict_add_list(progdict, "entries");
|
|
|
|
|
|
|
|
|
|
for (; listent; listent = listent->next) {
|
|
|
|
|
sb = listent->data;
|
|
|
|
|
if (sb->reported < next_step)
|
|
|
|
|
continue;
|
|
|
|
|
next_step += interval;
|
|
|
|
|
parser_arg cent = parser->list_add_dict(entlist);
|
|
|
|
|
ng_stats_ssrc_mos_entry(parser, cent, sb);
|
|
|
|
|
parser_arg ent = parser->list_add_dict(list);
|
|
|
|
|
|
|
|
|
|
parser->dict_add_int(ent, "SSRC", se->h.ssrc);
|
|
|
|
|
|
|
|
|
|
ng_stats_ssrc_1(parser, ent, se);
|
|
|
|
|
|
|
|
|
|
if (dict.gen && !parser->dict_contains(dict, tmp)) {
|
|
|
|
|
ent = parser->dict_add_dict_dup(dict, tmp);
|
|
|
|
|
ng_stats_ssrc_1(parser, ent, se);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|