/* call must be locked */ void ng_call_stats(struct call *call, const str *fromtag, const str *totag, bencode_item_t *output, struct call_stats *totals) { bencode_item_t *tags = NULL, *dict; const str *match_tag; GSList *l; struct call_monologue *ml; struct call_stats t_b; if (!totals) totals = &t_b; ZERO(*totals); if (!output) goto stats; call_bencode_hold_ref(call, output); bencode_dictionary_add_integer(output, "created", call->created); bencode_dictionary_add_integer(output, "last signal", call->last_signal); tags = bencode_dictionary_add_dictionary(output, "tags"); stats: match_tag = (totag && totag->s && totag->len) ? totag : fromtag; if (!match_tag || !match_tag->len) { for (l = call->monologues; l; l = l->next) { ml = l->data; ng_stats_monologue(tags, ml, totals); } } else { ml = g_hash_table_lookup(call->tags, match_tag); if (ml) { ng_stats_monologue(tags, ml, totals); ng_stats_monologue(tags, ml->active_dialogue, totals); } } if (!output) return; dict = bencode_dictionary_add_dictionary(output, "totals"); ng_stats(bencode_dictionary_add_dictionary(dict, "RTP"), &totals->totals[0], NULL); ng_stats(bencode_dictionary_add_dictionary(dict, "RTCP"), &totals->totals[1], NULL); }
static void ng_stats_stream(bencode_item_t *list, const struct packet_stream *ps, struct call_stats *totals) { bencode_item_t *dict = NULL, *flags; struct stats *s; if (!list) goto stats; dict = bencode_list_add_dictionary(list); if (ps->sfd) bencode_dictionary_add_integer(dict, "local port", ps->sfd->fd.localport); ng_stats_endpoint(bencode_dictionary_add_dictionary(dict, "endpoint"), &ps->endpoint); ng_stats_endpoint(bencode_dictionary_add_dictionary(dict, "advertised endpoint"), &ps->advertised_endpoint); if (ps->crypto.params.crypto_suite) bencode_dictionary_add_string(dict, "crypto suite", ps->crypto.params.crypto_suite->name); bencode_dictionary_add_integer(dict, "last packet", ps->last_packet); flags = bencode_dictionary_add_list(dict, "flags"); BF_PS("RTP", RTP); BF_PS("RTCP", RTCP); BF_PS("fallback RTCP", FALLBACK_RTCP); BF_PS("filled", FILLED); BF_PS("confirmed", CONFIRMED); BF_PS("kernelized", KERNELIZED); BF_PS("no kernel support", NO_KERNEL_SUPPORT); BF_PS("DTLS fingerprint verified", FINGERPRINT_VERIFIED); BF_PS("strict source address", STRICT_SOURCE); BF_PS("media handover", MEDIA_HANDOVER); stats: if (totals->last_packet < ps->last_packet) totals->last_packet = ps->last_packet; /* XXX distinguish between input and output */ s = &totals->totals[0]; if (!PS_ISSET(ps, RTP)) s = &totals->totals[1]; ng_stats(bencode_dictionary_add_dictionary(dict, "stats"), &ps->stats, s); }