Browse Source

TT#76206 fix call teardown for half established dialogues

In case of an offer with a via-branch followed by a delete without a
via-branch (cancelled call), the call erroneously remains open after
deleting one half of the call. The reason is that un-answered branches
do not appear in the `other_tags` list and so are left out from being
checked.

Change-Id: Ib008f32ef5ee06a7ca997c900c9a3adc85b0f10d
changes/04/37804/1
Richard Fuchs 6 years ago
parent
commit
3d83b46505
1 changed files with 13 additions and 10 deletions
  1. +13
    -10
      daemon/call.c

+ 13
- 10
daemon/call.c View File

@ -70,7 +70,7 @@ GHashTable *rtpe_callhash;
/* ********** */ /* ********** */
static void __monologue_destroy(struct call_monologue *monologue);
static void __monologue_destroy(struct call_monologue *monologue, int recurse);
static int monologue_destroy(struct call_monologue *ml); static int monologue_destroy(struct call_monologue *ml);
static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start, static struct timeval add_ongoing_calls_dur_in_interval(struct timeval *interval_start,
struct timeval *interval_duration); struct timeval *interval_duration);
@ -2561,10 +2561,9 @@ void call_media_unkernelize(struct call_media *media) {
} }
/* must be called with call->master_lock held in W */ /* must be called with call->master_lock held in W */
static void __monologue_destroy(struct call_monologue *monologue) {
static void __monologue_destroy(struct call_monologue *monologue, int recurse) {
struct call *call; struct call *call;
struct call_monologue *dialogue; struct call_monologue *dialogue;
GList *l;
call = monologue->call; call = monologue->call;
@ -2572,14 +2571,18 @@ static void __monologue_destroy(struct call_monologue *monologue) {
if (monologue->viabranch.s) if (monologue->viabranch.s)
g_hash_table_remove(call->viabranches, &monologue->viabranch); g_hash_table_remove(call->viabranches, &monologue->viabranch);
l = g_hash_table_get_values(monologue->other_tags);
while (l) {
for (GList *l = call->monologues.head; l; l = l->next) {
dialogue = l->data; dialogue = l->data;
l = g_list_delete_link(l, l);
if (dialogue == monologue)
continue;
if (dialogue->active_dialogue != monologue
&& !g_hash_table_lookup(dialogue->other_tags, &monologue->tag))
continue;
g_hash_table_remove(dialogue->other_tags, &monologue->tag); g_hash_table_remove(dialogue->other_tags, &monologue->tag);
if (!g_hash_table_size(dialogue->other_tags))
__monologue_destroy(dialogue);
if (recurse && !g_hash_table_size(dialogue->other_tags))
__monologue_destroy(dialogue, 0);
} }
monologue->deleted = 0; monologue->deleted = 0;
@ -2589,7 +2592,7 @@ static void __monologue_destroy(struct call_monologue *monologue) {
static int monologue_destroy(struct call_monologue *ml) { static int monologue_destroy(struct call_monologue *ml) {
struct call *c = ml->call; struct call *c = ml->call;
__monologue_destroy(ml);
__monologue_destroy(ml, 1);
if (g_hash_table_size(c->tags) < 2 && g_hash_table_size(c->viabranches) == 0) { if (g_hash_table_size(c->tags) < 2 && g_hash_table_size(c->viabranches) == 0) {
ilog(LOG_INFO, "Call branch '" STR_FORMAT_M "' (%s" STR_FORMAT "%svia-branch '" STR_FORMAT_M "') " ilog(LOG_INFO, "Call branch '" STR_FORMAT_M "' (%s" STR_FORMAT "%svia-branch '" STR_FORMAT_M "') "


Loading…
Cancel
Save