MT#57719 stop using `call_subscription` when getting dialogs

Previous implementation assumes that we use the `call_subscription`
objects in:
- `call_offer_answer_ng()`
- `call_update_lookup_udp()`
- `call_request_lookup_tcp()`

when appealing to the `call_get_mono_dialogue()`, in order to
get the `call_subscription` objects, in order to then pass it
for usage in the `monologue_offer_answer()`, where the most important
again is to use monologue references stored inside
the given `call_subscription` objects.

Instead of using the `call_subscription`, just use `call_monologue`
objects as a base data objects for this work,
which will allow us in the coming commits to deprecate
the `call_subscriptions` based model and
get to the subscription model based on medias.

Change-Id: Ia9ee5ba66522929acbceca28854ebccd3705635a
pull/1722/head
Donat Zenichev 2 years ago
parent 2a9564983b
commit 4bbbfba818

@ -2374,9 +2374,9 @@ static struct call_subscription *find_subscription(struct call_monologue *ml, st
}
__attribute__((nonnull(1, 2, 3, 5)))
__attribute__((nonnull(1, 2, 3)))
static void codecs_offer(struct call_media *media, struct call_media *other_media,
struct stream_params *sp, struct sdp_ng_flags *flags, struct call_subscription *dialogue[2])
struct stream_params *sp, struct sdp_ng_flags *flags)
{
ilogs(codec, LOG_DEBUG, "Updating codecs for offerer " STR_FORMAT " #%u",
STR_FMT(&other_media->monologue->tag),
@ -2439,13 +2439,15 @@ static void codecs_offer(struct call_media *media, struct call_media *other_medi
codec_tracker_update(&media->codecs);
// finally set up handlers again based on final results
codec_handlers_update(media, other_media, .flags = flags, .sp = sp, .sub = dialogue[1],
.allow_asymmetric = !!(flags && flags->allow_asymmetric_codecs));
codec_handlers_update(media, other_media, .flags = flags, .sp = sp,
.allow_asymmetric = !!(flags && flags->allow_asymmetric_codecs),
.reset_transcoding = true);
}
__attribute__((nonnull(1, 2, 3, 4, 5)))
__attribute__((nonnull(1, 2, 3, 4)))
static void codecs_answer(struct call_media *media, struct call_media *other_media,
struct stream_params *sp, struct sdp_ng_flags *flags, struct call_subscription *dialogue[2])
struct stream_params *sp, struct sdp_ng_flags *flags)
{
ilogs(codec, LOG_DEBUG, "Updating codecs for answerer " STR_FORMAT " #%u",
STR_FMT(&other_media->monologue->tag),
@ -2491,22 +2493,26 @@ static void codecs_answer(struct call_media *media, struct call_media *other_med
codec_tracker_update(&other_media->codecs);
// finally set up handlers again based on final results
codec_handlers_update(media, other_media, .flags = flags, .sp = sp, .sub = dialogue[1],
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
codec_handlers_update(other_media, media, .sub = dialogue[0],
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
codec_handlers_update(media, other_media, .flags = flags, .sp = sp,
.allow_asymmetric = !!flags->allow_asymmetric_codecs,
.reset_transcoding = true);
codec_handlers_update(other_media, media,
.allow_asymmetric = !!flags->allow_asymmetric_codecs,
.reset_transcoding = true);
// activate audio player if needed (not done by codec_handlers_update without `flags`)
audio_player_activate(media);
}
void codecs_offer_answer(struct call_media *media, struct call_media *other_media,
struct stream_params *sp, struct sdp_ng_flags *flags, struct call_subscription *dialogue[2])
struct stream_params *sp,
struct sdp_ng_flags *flags)
{
if (!flags || flags->opmode != OP_ANSWER)
codecs_offer(media, other_media, sp, flags, dialogue);
codecs_offer(media, other_media, sp, flags);
else
codecs_answer(media, other_media, sp, flags, dialogue);
codecs_answer(media, other_media, sp, flags);
}
@ -2769,13 +2775,13 @@ static void set_monologue_flags_per_subscribers(struct call_monologue *ml) {
}
/* called with call->master_lock held in W */
int monologue_offer_answer(struct call_subscription *dialogue[2], GQueue *streams,
int monologue_offer_answer(struct call_monologue *monologues[2], GQueue *streams,
struct sdp_ng_flags *flags)
{
struct call_media *media, *other_media;
struct endpoint_map *em;
struct call_monologue *other_ml = dialogue[0]->monologue;
struct call_monologue *monologue = dialogue[1]->monologue;
struct call_monologue *other_ml = monologues[0];
struct call_monologue *monologue = monologues[1];
unsigned int num_ports_this, num_ports_other;
/* we must have a complete dialogue, even though the to-tag (monologue->tag)
@ -2785,6 +2791,9 @@ int monologue_offer_answer(struct call_subscription *dialogue[2], GQueue *stream
return -1;
}
/* required for updating the transcoding attrs of subscriber */
struct call_subscription * cs = find_subscription(monologue, other_ml);
__call_monologue_init_from_flags(other_ml, flags);
if (flags && flags->exclude_recording) {
@ -2794,7 +2803,8 @@ int monologue_offer_answer(struct call_subscription *dialogue[2], GQueue *stream
__C_DBG("this="STR_FORMAT" other="STR_FORMAT, STR_FMT(&monologue->tag), STR_FMT(&other_ml->tag));
dialogue[1]->attrs.transcoding = 0;
if (cs)
cs->attrs.transcoding = 0;
for (GList *sp_iter = streams->head; sp_iter; sp_iter = sp_iter->next) {
struct stream_params *sp = sp_iter->data;
@ -2814,7 +2824,7 @@ int monologue_offer_answer(struct call_subscription *dialogue[2], GQueue *stream
__media_init_from_flags(other_media, media, sp, flags);
codecs_offer_answer(media, other_media, sp, flags, dialogue);
codecs_offer_answer(media, other_media, sp, flags);
/* send and recv are from our POV */
bf_copy_same(&media->media_flags, &sp->sp_flags,
@ -3486,8 +3496,9 @@ int monologue_subscribe_answer(struct call_monologue *dst_ml, struct sdp_ng_flag
codec_handlers_update(src_media, dst_media, .flags = flags,
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
codec_handlers_update(dst_media, src_media, .flags = flags, .sp = sp, .sub = rev_cs,
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
codec_handlers_update(dst_media, src_media, .flags = flags, .sp = sp,
.allow_asymmetric = !!flags->allow_asymmetric_codecs,
.reset_transcoding = true);
__dtls_logic(flags, dst_media, sp);
@ -4472,8 +4483,9 @@ static bool call_viabranch_intact_monologue(const str * viabranch, struct call_m
*
* `dialogue` must be initialised to zero.
*/
static int call_get_monologue_new(struct call_subscription *dialogue[2], struct call *call,
const str *fromtag, const str *totag,
static int call_get_monologue_new(struct call_monologue *monologues[2], struct call *call,
const str *fromtag,
const str *totag,
const str *viabranch)
{
struct call_monologue *ret, *os = NULL; /* ret - initial offer, os - other side */
@ -4517,7 +4529,6 @@ static int call_get_monologue_new(struct call_subscription *dialogue[2], struct
// use existing to-tag
__monologue_unkernelize(csm, "dialogue association changed");
__subscribe_offer_answer_both_ways(ret, csm);
__offer_answer_get_subscriptions(ret, csm, dialogue);
break;
}
break; // there should only be one
@ -4547,7 +4558,6 @@ static int call_get_monologue_new(struct call_subscription *dialogue[2], struct
/* previously seen branch. use it */
__monologue_unkernelize(os, "dialogue/branch association changed");
__subscribe_offer_answer_both_ways(ret, os);
__offer_answer_get_subscriptions(ret, os, dialogue);
goto ok_check_tag;
}
@ -4557,7 +4567,6 @@ new_branch:
__C_DBG("create new \"other side\" monologue for viabranch "STR_FORMAT, STR_FMT0(viabranch));
os = __monologue_create(call);
__subscribe_offer_answer_both_ways(ret, os);
__offer_answer_get_subscriptions(ret, os, dialogue);
__monologue_viabranch(os, viabranch);
ok_check_tag:
@ -4576,7 +4585,8 @@ ok_check_tag:
if (G_UNLIKELY(!os))
return -1;
__tags_associate(ret, os);
__tags_get_subscriptions(ret, os, dialogue);
monologues[0] = ret;
monologues[1] = os;
return 0;
}
@ -4592,7 +4602,8 @@ ok_check_tag:
*
* `dialogue` must be initialised to zero.
*/
static int call_get_dialogue(struct call_subscription *dialogue[2], struct call *call, const str *fromtag,
static int call_get_dialogue(struct call_monologue *monologues[2], struct call *call,
const str *fromtag,
const str *totag,
const str *viabranch)
{
@ -4604,7 +4615,7 @@ static int call_get_dialogue(struct call_subscription *dialogue[2], struct call
/* we start with the to-tag. if it's not known, we treat it as a branched offer */
tt = call_get_monologue(call, totag);
if (!tt)
return call_get_monologue_new(dialogue, call, fromtag, totag, viabranch);
return call_get_monologue_new(monologues, call, fromtag, totag, viabranch);
/* if the from-tag is known already, return that */
ft = call_get_monologue(call, fromtag);
@ -4659,32 +4670,35 @@ tag_setup:
dialogue_unkernelize(ft, "dialogue signalling event");
dialogue_unkernelize(tt, "dialogue signalling event");
__subscribe_offer_answer_both_ways(ft, tt);
__offer_answer_get_subscriptions(ft, tt, dialogue);
done:
__monologue_unkernelize(ft, "dialogue signalling event");
dialogue_unkernelize(ft, "dialogue signalling event");
__tags_associate(ft, tt);
__tags_get_subscriptions(ft, tt, dialogue);
/* just provide gotten dialogs,
* which have all needed information about subscribers/subscriptions */
monologues[0] = ft;
monologues[1] = tt;
return 0;
}
/* fromtag and totag strictly correspond to the directionality of the message, not to the actual
* SIP headers. IOW, the fromtag corresponds to the monologue sending this message, even if the
* tag is actually from the TO header of the SIP message (as it would be in a 200 OK) */
int call_get_mono_dialogue(struct call_subscription *dialogue[2], struct call *call, const str *fromtag,
int call_get_mono_dialogue(struct call_monologue *monologues[2], struct call *call,
const str *fromtag,
const str *totag,
const str *viabranch)
{
dialogue[0] = dialogue[1] = NULL;
/* initial offer */
if (!totag || !totag->s)
return call_get_monologue_new(monologues, call, fromtag, NULL, viabranch);
if (!totag || !totag->s) /* initial offer */
return call_get_monologue_new(dialogue, call, fromtag, NULL, viabranch);
return call_get_dialogue(dialogue, call, fromtag, totag, viabranch);
return call_get_dialogue(monologues, call, fromtag, totag, viabranch);
}
static void media_stop(struct call_media *m) {
if (!m)
return;

@ -166,7 +166,7 @@ static str *call_update_lookup_udp(char **out, enum call_opmode opmode, const ch
const endpoint_t *sin)
{
struct call *c;
struct call_subscription *dialogue[2];
struct call_monologue *monologues[2]; /* subscriber lists of both monologues */
GQueue q = G_QUEUE_INIT;
struct stream_params sp;
str *ret;
@ -187,11 +187,11 @@ static str *call_update_lookup_udp(char **out, enum call_opmode opmode, const ch
updated_created_from(c, addr, sin);
if (call_get_mono_dialogue(dialogue, c, &fromtag, &totag, NULL))
if (call_get_mono_dialogue(monologues, c, &fromtag, &totag, NULL))
goto ml_fail;
struct call_monologue *from_ml = dialogue[0]->monologue;
struct call_monologue *to_ml = dialogue[1]->monologue;
struct call_monologue *from_ml = monologues[0];
struct call_monologue *to_ml = monologues[1];
if (opmode == OP_OFFER) {
from_ml->tagtype = FROM_TAG;
@ -203,7 +203,7 @@ static str *call_update_lookup_udp(char **out, enum call_opmode opmode, const ch
goto addr_fail;
g_queue_push_tail(&q, &sp);
i = monologue_offer_answer(dialogue, &q, NULL);
i = monologue_offer_answer(monologues, &q, NULL);
g_queue_clear(&q);
if (i)
@ -321,7 +321,7 @@ INLINE void call_unlock_release_update(struct call **c) {
static str *call_request_lookup_tcp(char **out, enum call_opmode opmode) {
struct call *c;
struct call_subscription *dialogue[2];
struct call_monologue *monologues[2];
AUTO_CLEANUP(GQueue s, sdp_streams_free) = G_QUEUE_INIT;
str *ret = NULL;
GHashTable *infohash;
@ -350,14 +350,14 @@ static str *call_request_lookup_tcp(char **out, enum call_opmode opmode) {
str_swap(&fromtag, &totag);
}
if (call_get_mono_dialogue(dialogue, c, &fromtag, &totag, NULL)) {
if (call_get_mono_dialogue(monologues, c, &fromtag, &totag, NULL)) {
ilog(LOG_WARNING, "Invalid dialogue association");
goto out2;
}
if (monologue_offer_answer(dialogue, &s, NULL))
if (monologue_offer_answer(monologues, &s, NULL))
goto out2;
ret = streams_print(dialogue[1]->monologue->medias, 1, s.length, NULL, SAF_TCP);
ret = streams_print(monologues[1]->medias, 1, s.length, NULL, SAF_TCP);
out2:
call_unlock_release_update(&c);
@ -1958,7 +1958,7 @@ static const char *call_offer_answer_ng(struct ng_buffer *ngbuf, bencode_item_t
AUTO_CLEANUP(GQueue parsed, sdp_free) = G_QUEUE_INIT;
AUTO_CLEANUP(GQueue streams, sdp_streams_free) = G_QUEUE_INIT;
struct call *call;
struct call_subscription *dialogue[2];
struct call_monologue * monologues[2];
int ret;
AUTO_CLEANUP(struct sdp_ng_flags flags, call_ng_free_flags);
struct sdp_chopper *chopper;
@ -2039,15 +2039,15 @@ static const char *call_offer_answer_ng(struct ng_buffer *ngbuf, bencode_item_t
call_bencode_hold_ref(call, output);
errstr = "Invalid dialogue association";
if (call_get_mono_dialogue(dialogue, call, &flags.from_tag, &flags.to_tag,
if (call_get_mono_dialogue(monologues, call, &flags.from_tag, &flags.to_tag,
flags.via_branch.s ? &flags.via_branch : NULL)) {
rwlock_unlock_w(&call->master_lock);
obj_put(call);
goto out;
}
struct call_monologue *from_ml = dialogue[0]->monologue;
struct call_monologue *to_ml = dialogue[1]->monologue;
struct call_monologue *from_ml = monologues[0];
struct call_monologue *to_ml = monologues[1];
if (opmode == OP_OFFER) {
from_ml->tagtype = FROM_TAG;
@ -2069,7 +2069,7 @@ static const char *call_offer_answer_ng(struct ng_buffer *ngbuf, bencode_item_t
call->drop_traffic = 0;
}
ret = monologue_offer_answer(dialogue, &streams, &flags);
ret = monologue_offer_answer(monologues, &streams, &flags);
if (!ret)
ret = sdp_replace(chopper, &parsed, to_ml, &flags);
if (!ret)

@ -995,16 +995,26 @@ static int __codec_handler_eq(const void *a, const void *b) {
&& h->sink == j->sink;
}
// call must be locked in W
/**
* receiver - media / sink - other_media
* call must be locked in W
*/
void __codec_handlers_update(struct call_media *receiver, struct call_media *sink,
struct chu_args a)
{
struct call_monologue *monologue = receiver->monologue;
struct call_monologue *other_monologue = sink->monologue;
/* required for updating the transcoding attrs of subscriber */
struct call_subscription * cs = call_get_call_subscription(monologue->subscribers_ht, other_monologue);
ilogs(codec, LOG_DEBUG, "Setting up codec handlers for " STR_FORMAT_M " #%u -> " STR_FORMAT_M " #%u",
STR_FMT_M(&receiver->monologue->tag), receiver->index,
STR_FMT_M(&sink->monologue->tag), sink->index);
if (a.sub)
a.sub->attrs.transcoding = 0;
if (a.reset_transcoding && cs)
cs->attrs.transcoding = 0;
MEDIA_CLEAR(receiver, GENERATOR);
MEDIA_CLEAR(sink, GENERATOR);
@ -1016,8 +1026,8 @@ void __codec_handlers_update(struct call_media *receiver, struct call_media *sin
// non-RTP protocol?
if (proto_is(receiver->protocol, PROTO_UDPTL)) {
if (codec_handler_udptl_update(receiver, sink, a.flags)) {
if (a.sub)
a.sub->attrs.transcoding = 1;
if (a.reset_transcoding && cs)
cs->attrs.transcoding = 1;
return;
}
}
@ -1032,8 +1042,8 @@ void __codec_handlers_update(struct call_media *receiver, struct call_media *sin
// should we transcode to a non-RTP protocol?
if (proto_is_not_rtp(sink->protocol)) {
if (codec_handler_non_rtp_update(receiver, sink, a.flags, a.sp)) {
if (a.sub)
a.sub->attrs.transcoding = 1;
if (a.reset_transcoding && cs)
cs->attrs.transcoding = 1;
return;
}
}
@ -1369,8 +1379,8 @@ next:
MEDIA_SET(sink, AUDIO_PLAYER);
if (is_transcoding) {
if (a.sub)
a.sub->attrs.transcoding = 1;
if (a.reset_transcoding && cs)
cs->attrs.transcoding = 1;
if (!use_audio_player) {
// we have to translate RTCP packets

@ -1861,7 +1861,7 @@ static int json_link_medias(struct call *c, struct redis_list *medias,
continue;
other_m->monologue = other_ml;
if (other_m->index == med->index) {
codec_handlers_update(other_m, med, .sub = cs);
codec_handlers_update(other_m, med, .reset_transcoding = true);
break;
}
}

@ -734,16 +734,18 @@ void call_subscriptions_clear(GQueue *q);
struct call *call_get_or_create(const str *callid, bool foreign, bool exclusive);
struct call *call_get_opmode(const str *callid, enum call_opmode opmode);
void call_make_own_foreign(struct call *c, bool foreign);
int call_get_mono_dialogue(struct call_subscription *dialogue[2], struct call *call, const str *fromtag,
int call_get_mono_dialogue(struct call_monologue *monologues[2], struct call *call,
const str *fromtag,
const str *totag,
const str *viabranch);
struct call_monologue *call_get_monologue(struct call *call, const str *fromtag);
struct call_monologue *call_get_or_create_monologue(struct call *call, const str *fromtag);
struct call *call_get(const str *callid);
int monologue_offer_answer(struct call_subscription *dialogue[2], GQueue *streams, struct sdp_ng_flags *flags);
__attribute__((nonnull(1, 2, 3, 5)))
int monologue_offer_answer(struct call_monologue *monologues[2], GQueue *streams, struct sdp_ng_flags *flags);
__attribute__((nonnull(1, 2, 3)))
void codecs_offer_answer(struct call_media *media, struct call_media *other_media,
struct stream_params *sp, struct sdp_ng_flags *flags, struct call_subscription *dialogue[2]);
struct stream_params *sp,
struct sdp_ng_flags *flags);
int monologue_publish(struct call_monologue *ml, GQueue *streams, struct sdp_ng_flags *flags);
int monologue_subscribe_request(const GQueue *srcs, struct call_monologue *dst, struct sdp_ng_flags *);
int monologue_subscribe_answer(struct call_monologue *dst, struct sdp_ng_flags *,

@ -1,7 +1,6 @@
#ifndef __CODEC_H__
#define __CODEC_H__
#include <glib.h>
#include <sys/time.h>
#include <stdbool.h>
@ -172,8 +171,8 @@ void payload_type_clear(struct rtp_payload_type *p);
struct chu_args {
const struct sdp_ng_flags *flags;
const struct stream_params *sp;
struct call_subscription *sub;
bool allow_asymmetric;
bool reset_transcoding;
};
#define codec_handlers_update(r, s, ...) \
__codec_handlers_update(r, s, (struct chu_args) {__VA_ARGS__})

@ -167,18 +167,16 @@ static void __sdp_pt_fmt(int num, str codec, int clockrate, int channels, str fu
static void offer(void) {
printf("offer\n");
flags.opmode = OP_OFFER;
struct call_subscription subs[2];
struct call_subscription *subs_p[2] = {&subs[0], &subs[1]};
codecs_offer_answer(media_B, media_A, &rtp_types_sp, &flags, subs_p);
codecs_offer_answer(media_B, media_A, &rtp_types_sp, &flags);
__init();
}
static void answer(void) {
printf("answer\n");
flags.opmode = OP_ANSWER;
struct call_subscription subs[2];
struct call_subscription *subs_p[2] = {&subs[0], &subs[1]};
codecs_offer_answer(media_A, media_B, &rtp_types_sp, &flags, subs_p);
codecs_offer_answer(media_A, media_B, &rtp_types_sp, &flags);
__init();
}

Loading…
Cancel
Save