|
|
@ -182,7 +182,7 @@ static void call_timer_iterator(void *key, void *val, void *ptr) { |
|
|
rwlock_lock_r(&cm->conf.config_lock); |
|
|
rwlock_lock_r(&cm->conf.config_lock); |
|
|
|
|
|
|
|
|
// final timeout applicable to all calls (own and foreign) |
|
|
// final timeout applicable to all calls (own and foreign) |
|
|
if (cm->conf.final_timeout && poller_now >= (c->created + cm->conf.final_timeout)) { |
|
|
|
|
|
|
|
|
if (cm->conf.final_timeout && poller_now >= (c->created.tv_sec + cm->conf.final_timeout)) { |
|
|
ilog(LOG_INFO, "Closing call due to final timeout"); |
|
|
ilog(LOG_INFO, "Closing call due to final timeout"); |
|
|
tmp_t_reason = FINAL_TIMEOUT; |
|
|
tmp_t_reason = FINAL_TIMEOUT; |
|
|
for (it = c->monologues.head; it; it = it->next) { |
|
|
for (it = c->monologues.head; it; it = it->next) { |
|
|
@ -1845,66 +1845,91 @@ void call_destroy(struct call *c) { |
|
|
rwlock_lock_w(&c->master_lock); |
|
|
rwlock_lock_w(&c->master_lock); |
|
|
/* at this point, no more packet streams can be added */ |
|
|
/* at this point, no more packet streams can be added */ |
|
|
|
|
|
|
|
|
if (IS_OWN_CALL(c)) { |
|
|
|
|
|
ilog(LOG_INFO, "Final packet stats:"); |
|
|
|
|
|
|
|
|
if (!IS_OWN_CALL(c)) |
|
|
|
|
|
goto no_stats_output; |
|
|
|
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "Final packet stats:"); |
|
|
|
|
|
|
|
|
for (l = c->monologues.head; l; l = l->next) { |
|
|
|
|
|
ml = l->data; |
|
|
|
|
|
|
|
|
for (l = c->monologues.head; l; l = l->next) { |
|
|
|
|
|
ml = l->data; |
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "--- Tag '"STR_FORMAT"', created " |
|
|
|
|
|
"%u:%02u ago for branch '"STR_FORMAT"', in dialogue with '"STR_FORMAT"'", |
|
|
|
|
|
STR_FMT(&ml->tag), |
|
|
|
|
|
(unsigned int) (poller_now - ml->created) / 60, |
|
|
|
|
|
(unsigned int) (poller_now - ml->created) % 60, |
|
|
|
|
|
STR_FMT(&ml->viabranch), |
|
|
|
|
|
ml->active_dialogue ? ml->active_dialogue->tag.len : 6, |
|
|
|
|
|
ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)"); |
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "--- Tag '"STR_FORMAT"', created " |
|
|
|
|
|
"%u:%02u ago for branch '"STR_FORMAT"', in dialogue with '"STR_FORMAT"'", |
|
|
|
|
|
STR_FMT(&ml->tag), |
|
|
|
|
|
(unsigned int) (poller_now - ml->created) / 60, |
|
|
|
|
|
(unsigned int) (poller_now - ml->created) % 60, |
|
|
|
|
|
STR_FMT(&ml->viabranch), |
|
|
|
|
|
ml->active_dialogue ? ml->active_dialogue->tag.len : 6, |
|
|
|
|
|
ml->active_dialogue ? ml->active_dialogue->tag.s : "(none)"); |
|
|
|
|
|
|
|
|
for (k = ml->medias.head; k; k = k->next) { |
|
|
|
|
|
md = k->data; |
|
|
|
|
|
|
|
|
for (k = ml->medias.head; k; k = k->next) { |
|
|
|
|
|
md = k->data; |
|
|
|
|
|
|
|
|
rtp_pt = __rtp_stats_codec(md); |
|
|
|
|
|
|
|
|
rtp_pt = __rtp_stats_codec(md); |
|
|
#define MLL_PREFIX "------ Media #%u ("STR_FORMAT" over %s) using " /* media log line prefix */ |
|
|
#define MLL_PREFIX "------ Media #%u ("STR_FORMAT" over %s) using " /* media log line prefix */ |
|
|
#define MLL_COMMON /* common args */ \ |
|
|
#define MLL_COMMON /* common args */ \ |
|
|
md->index, \ |
|
|
|
|
|
STR_FMT(&md->type), \ |
|
|
|
|
|
md->protocol ? md->protocol->name : "(unknown)" |
|
|
|
|
|
if (!rtp_pt) |
|
|
|
|
|
ilog(LOG_INFO, MLL_PREFIX "unknown codec", MLL_COMMON); |
|
|
|
|
|
else |
|
|
|
|
|
ilog(LOG_INFO, MLL_PREFIX STR_FORMAT, MLL_COMMON, |
|
|
|
|
|
STR_FMT(&rtp_pt->encoding_with_params)); |
|
|
|
|
|
|
|
|
|
|
|
for (o = md->streams.head; o; o = o->next) { |
|
|
|
|
|
ps = o->data; |
|
|
|
|
|
|
|
|
|
|
|
if (PS_ISSET(ps, FALLBACK_RTCP)) |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
char *addr = sockaddr_print_buf(&ps->endpoint.address); |
|
|
|
|
|
char *local_addr = ps->selected_sfd ? sockaddr_print_buf(&ps->selected_sfd->socket.local.address) : "0.0.0.0"; |
|
|
|
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "--------- Port %15s:%-5u <> %15s:%-5u%s, SSRC %" PRIu32 ", " |
|
|
|
|
|
""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" last_packet", |
|
|
|
|
|
local_addr, |
|
|
|
|
|
(unsigned int) (ps->selected_sfd ? ps->selected_sfd->socket.local.port : 0), |
|
|
|
|
|
addr, ps->endpoint.port, |
|
|
|
|
|
(!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? " (RTCP)" : "", |
|
|
|
|
|
ps->ssrc_in ? ps->ssrc_in->parent->ssrc : 0, |
|
|
|
|
|
atomic64_get(&ps->stats.packets), |
|
|
|
|
|
atomic64_get(&ps->stats.bytes), |
|
|
|
|
|
atomic64_get(&ps->stats.errors), |
|
|
|
|
|
atomic64_get(&ps->last_packet)); |
|
|
|
|
|
|
|
|
|
|
|
statistics_update_totals(m,ps); |
|
|
|
|
|
|
|
|
md->index, \ |
|
|
|
|
|
STR_FMT(&md->type), \ |
|
|
|
|
|
md->protocol ? md->protocol->name : "(unknown)" |
|
|
|
|
|
if (!rtp_pt) |
|
|
|
|
|
ilog(LOG_INFO, MLL_PREFIX "unknown codec", MLL_COMMON); |
|
|
|
|
|
else |
|
|
|
|
|
ilog(LOG_INFO, MLL_PREFIX STR_FORMAT, MLL_COMMON, |
|
|
|
|
|
STR_FMT(&rtp_pt->encoding_with_params)); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for (o = md->streams.head; o; o = o->next) { |
|
|
|
|
|
ps = o->data; |
|
|
|
|
|
|
|
|
|
|
|
if (PS_ISSET(ps, FALLBACK_RTCP)) |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
char *addr = sockaddr_print_buf(&ps->endpoint.address); |
|
|
|
|
|
char *local_addr = ps->selected_sfd ? sockaddr_print_buf(&ps->selected_sfd->socket.local.address) : "0.0.0.0"; |
|
|
|
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "--------- Port %15s:%-5u <> %15s:%-5u%s, SSRC %" PRIu32 ", " |
|
|
|
|
|
""UINT64F" p, "UINT64F" b, "UINT64F" e, "UINT64F" ts", |
|
|
|
|
|
local_addr, |
|
|
|
|
|
(unsigned int) (ps->selected_sfd ? ps->selected_sfd->socket.local.port : 0), |
|
|
|
|
|
addr, ps->endpoint.port, |
|
|
|
|
|
(!PS_ISSET(ps, RTP) && PS_ISSET(ps, RTCP)) ? " (RTCP)" : "", |
|
|
|
|
|
ps->ssrc_in ? ps->ssrc_in->parent->ssrc : 0, |
|
|
|
|
|
atomic64_get(&ps->stats.packets), |
|
|
|
|
|
atomic64_get(&ps->stats.bytes), |
|
|
|
|
|
atomic64_get(&ps->stats.errors), |
|
|
|
|
|
g_now.tv_sec - atomic64_get(&ps->last_packet)); |
|
|
|
|
|
|
|
|
|
|
|
statistics_update_totals(m,ps); |
|
|
|
|
|
|
|
|
ice_shutdown(&md->ice_agent); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ice_shutdown(&md->ice_agent); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
k = g_hash_table_get_values(c->ssrc_hash->ht); |
|
|
|
|
|
for (l = k; l; l = l->next) { |
|
|
|
|
|
struct ssrc_entry *se = l->data; |
|
|
|
|
|
|
|
|
|
|
|
if (!se->stats_blocks.length || !se->lowest_mos || !se->highest_mos) |
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
ilog(LOG_INFO, "--- SSRC %" PRIu32 "", se->ssrc); |
|
|
|
|
|
ilog(LOG_INFO, "------ Average MOS %i.%i, lowest MOS %i.%i (at %u:%02u), " |
|
|
|
|
|
"highest MOS %i.%i (at %u:%02u)", |
|
|
|
|
|
(int) (se->mos_sum / se->stats_blocks.length / 10), |
|
|
|
|
|
abs(se->mos_sum / se->stats_blocks.length % 10), |
|
|
|
|
|
se->lowest_mos->mos / 10, |
|
|
|
|
|
abs(se->lowest_mos->mos % 10), |
|
|
|
|
|
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) / 60, |
|
|
|
|
|
(unsigned int) (timeval_diff(&se->lowest_mos->reported, &c->created) / 1000000) % 60, |
|
|
|
|
|
se->highest_mos->mos / 10, |
|
|
|
|
|
abs(se->highest_mos->mos % 10), |
|
|
|
|
|
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) / 60, |
|
|
|
|
|
(unsigned int) (timeval_diff(&se->highest_mos->reported, &c->created) / 1000000) % 60); |
|
|
|
|
|
} |
|
|
|
|
|
g_list_free(k); |
|
|
|
|
|
|
|
|
|
|
|
no_stats_output: |
|
|
statistics_update_oneway(c); |
|
|
statistics_update_oneway(c); |
|
|
|
|
|
|
|
|
cdr_update_entry(c); |
|
|
cdr_update_entry(c); |
|
|
@ -2033,7 +2058,7 @@ static struct call *call_create(const str *callid, struct callmaster *m) { |
|
|
c->tags = g_hash_table_new(str_hash, str_equal); |
|
|
c->tags = g_hash_table_new(str_hash, str_equal); |
|
|
c->viabranches = g_hash_table_new(str_hash, str_equal); |
|
|
c->viabranches = g_hash_table_new(str_hash, str_equal); |
|
|
call_str_cpy(c, &c->callid, callid); |
|
|
call_str_cpy(c, &c->callid, callid); |
|
|
c->created = poller_now; |
|
|
|
|
|
|
|
|
c->created = g_now; |
|
|
c->dtls_cert = dtls_cert(); |
|
|
c->dtls_cert = dtls_cert(); |
|
|
c->tos = m->conf.default_tos; |
|
|
c->tos = m->conf.default_tos; |
|
|
c->ssrc_hash = create_ssrc_hash(); |
|
|
c->ssrc_hash = create_ssrc_hash(); |
|
|
|