|
|
|
@ -4443,75 +4443,6 @@ static bool call_monologues_associations_left(call_t * c) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Check whether given totag is already subscribed to the given monologue medias. |
|
|
|
* Returns: true - subscribed, false - not subscribed. |
|
|
|
*/ |
|
|
|
static bool call_totag_subscribed_to_monologue(const str * totag, const struct call_monologue * monologue) |
|
|
|
{ |
|
|
|
if (!totag || !totag->s) |
|
|
|
return false; |
|
|
|
|
|
|
|
for (int i = 0; i < monologue->medias->len; i++) |
|
|
|
{ |
|
|
|
struct call_media * media = monologue->medias->pdata[i]; |
|
|
|
if (!media) |
|
|
|
continue; |
|
|
|
|
|
|
|
for (__auto_type subscriber = media->media_subscribers.head; |
|
|
|
subscriber; |
|
|
|
subscriber = subscriber->next) |
|
|
|
{ |
|
|
|
struct media_subscription * ms = subscriber->data; |
|
|
|
if (!ms->attrs.offer_answer) /* is this really needed? */ |
|
|
|
continue; |
|
|
|
|
|
|
|
struct call_monologue * subscriber_monologue = ms->monologue; |
|
|
|
if (!str_cmp_str(&subscriber_monologue->tag, totag)) /* subscriber found */ |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
/** |
|
|
|
* Check whether given viabranch is intact with a monologue, which owns |
|
|
|
* existing media subscribriptions to it. |
|
|
|
* |
|
|
|
* It tags a monologue, media of which is subscribed to given monologue, using given viabranch, |
|
|
|
* in case previous other side hasn't been tagged with the via-branch |
|
|
|
* |
|
|
|
* Returns: true - intact, false - not intact. |
|
|
|
*/ |
|
|
|
static bool call_viabranch_intact_monologue(const str * viabranch, struct call_monologue * monologue) |
|
|
|
{ |
|
|
|
for (int i = 0; i < monologue->medias->len; i++) |
|
|
|
{ |
|
|
|
struct call_media * media = monologue->medias->pdata[i]; |
|
|
|
if (!media) |
|
|
|
continue; |
|
|
|
|
|
|
|
for (__auto_type subscriber = media->media_subscribers.head; |
|
|
|
subscriber; |
|
|
|
subscriber = subscriber->next) |
|
|
|
{ |
|
|
|
struct media_subscription * ms = subscriber->data; |
|
|
|
struct call_monologue * subscriber_monologue = ms->monologue; |
|
|
|
|
|
|
|
/* 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. */ |
|
|
|
if (!subscriber_monologue->viabranch.s) { |
|
|
|
/* previous "other side" hasn't been tagged with the via-branch, so we'll just |
|
|
|
* use this one and tag it */ |
|
|
|
__monologue_viabranch(subscriber_monologue, viabranch); |
|
|
|
return true; |
|
|
|
} |
|
|
|
if (!str_cmp_str(&subscriber_monologue->viabranch, viabranch)) |
|
|
|
return true; /* dialogue still intact */ |
|
|
|
} |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Based on given From-tag create a new monologue for this dialog, |
|
|
|
* if given tag wasn't present in 'tags' of this call. |
|
|
|
@ -4559,25 +4490,24 @@ static int call_get_monologue_new(struct call_monologue *monologues[2], call_t * |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* If to-tag is presented, confirm that media associations are intact. |
|
|
|
/* If to-tag is present, retrieve it. |
|
|
|
* Create a new monologue for the other side, if the monologue with such to-tag not found. |
|
|
|
*/ |
|
|
|
if (totag && totag->s && |
|
|
|
!call_totag_subscribed_to_monologue(totag, ret)) |
|
|
|
{ |
|
|
|
if (totag && totag->s) { |
|
|
|
struct call_monologue * monologue = call_get_monologue(call, totag); |
|
|
|
if (!monologue) |
|
|
|
goto new_branch; |
|
|
|
} |
|
|
|
|
|
|
|
if (!viabranch || call_viabranch_intact_monologue(viabranch, ret)) { |
|
|
|
goto monologues_intact; |
|
|
|
if (!viabranch) { |
|
|
|
/* dialogue complete */ |
|
|
|
goto have_dialogue; |
|
|
|
} else { |
|
|
|
os = t_hash_table_lookup(call->viabranches, viabranch); |
|
|
|
if (os) { |
|
|
|
/* previously seen branch, use it */ |
|
|
|
__monologue_unconfirm(os, "dialogue/branch association changed"); |
|
|
|
goto monologues_intact; |
|
|
|
goto have_dialogue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -4588,7 +4518,7 @@ new_branch: |
|
|
|
os = __monologue_create(call); |
|
|
|
__monologue_viabranch(os, viabranch); |
|
|
|
|
|
|
|
monologues_intact: |
|
|
|
have_dialogue: |
|
|
|
for (unsigned int i = 0; i < ret->medias->len; i++) |
|
|
|
{ |
|
|
|
struct call_media *media = ret->medias->pdata[i]; |
|
|
|
@ -4605,11 +4535,11 @@ monologues_intact: |
|
|
|
__monologue_tag(ms->monologue, totag); |
|
|
|
/* There should be only one monologue? |
|
|
|
* TODO: check if there's more than one-to-one mapping */ |
|
|
|
goto monologues_intact_finalize; |
|
|
|
goto finish; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
monologues_intact_finalize: |
|
|
|
finish: |
|
|
|
if (G_UNLIKELY(!os)) |
|
|
|
return -1; |
|
|
|
__tags_associate(ret, os); |
|
|
|
|