Browse Source

support branched offer with previously unseen to-tag

alutay/test_viabranch
Richard Fuchs 11 years ago
parent
commit
811fe2b59e
1 changed files with 17 additions and 11 deletions
  1. +17
    -11
      daemon/call.c

+ 17
- 11
daemon/call.c View File

@ -2872,19 +2872,22 @@ static void __monologue_destroy(struct call_monologue *monologue) {
}
/* must be called with call->master_lock held in W */
static struct call_monologue *call_get_monologue(struct call *call, const str *fromtag, const str *viabranch) {
static struct call_monologue *call_get_monologue(struct call *call, const str *fromtag, const str *totag,
const str *viabranch)
{
struct call_monologue *ret, *os;
__C_DBG("getting monologue for tag '"STR_FORMAT"' in call '"STR_FORMAT"'",
STR_FMT(fromtag), STR_FMT(&call->callid));
ret = g_hash_table_lookup(call->tags, fromtag);
/* XXX reverse the conditional */
if (ret) {
__C_DBG("found existing monologue");
__monologue_unkernelize(ret);
__monologue_unkernelize(ret->active_dialogue);
if (!viabranch)
return ret;
goto ok_check_tag;
/* check the viabranch. if it's not known, then this is a branched offer and we need
* to create a new "other side" for this branch. */
@ -2892,17 +2895,17 @@ static struct call_monologue *call_get_monologue(struct call *call, const str *f
/* previous "other side" hasn't been tagged with the via-branch, so we'll just
* use this one and tag it */
__monologue_viabranch(ret->active_dialogue, viabranch);
return ret;
goto ok_check_tag;
}
if (!str_cmp_str(&ret->active_dialogue->viabranch, viabranch))
return ret; /* dialogue still intact */
goto ok_check_tag; /* dialogue still intact */
os = g_hash_table_lookup(call->viabranches, viabranch);
if (os) {
/* previously seen branch. use it */
__monologue_unkernelize(os);
os->active_dialogue = ret;
ret->active_dialogue = os;
return ret;
goto ok_check_tag;
}
goto new_branch;
}
@ -2917,6 +2920,9 @@ new_branch:
ret->active_dialogue = __monologue_create(call);
__monologue_viabranch(ret->active_dialogue, viabranch);
ok_check_tag:
if (totag && totag->s && !ret->active_dialogue->tag.s)
__monologue_tag(ret->active_dialogue, totag);
return ret;
}
@ -2929,6 +2935,11 @@ static struct call_monologue *call_get_dialogue(struct call *call, const str *fr
__C_DBG("getting dialogue for tags '"STR_FORMAT"'<>'"STR_FORMAT"' in call '"STR_FORMAT"'",
STR_FMT(fromtag), STR_FMT(totag), STR_FMT(&call->callid));
/* we start with the to-tag. if it's not known, we treat it as a branched offer */
tt = g_hash_table_lookup(call->tags, totag);
if (!tt)
return call_get_monologue(call, fromtag, totag, viabranch);
/* if the from-tag is known already, return that */
ft = g_hash_table_lookup(call->tags, fromtag);
if (ft) {
@ -2945,11 +2956,6 @@ static struct call_monologue *call_get_dialogue(struct call *call, const str *fr
ft = g_hash_table_lookup(call->viabranches, viabranch);
}
/* the to-tag has to be known. it's an error if it isn't */
tt = g_hash_table_lookup(call->tags, totag);
if (!tt)
return NULL;
if (!ft) {
/* if we don't have a fromtag monologue yet, we can use a half-complete dialogue
* from the totag if there is one. otherwise we have to create a new one. */
@ -2983,7 +2989,7 @@ struct call_monologue *call_get_mono_dialogue(struct call *call, const str *from
const str *viabranch)
{
if (!totag || !totag->s) /* initial offer */
return call_get_monologue(call, fromtag, viabranch);
return call_get_monologue(call, fromtag, NULL, viabranch);
return call_get_dialogue(call, fromtag, totag, viabranch);
}


Loading…
Cancel
Save