MT#61368 add dialogue_connect()

This function connects two call legs (two monologues), possibly from
different call IDs, into a single media flow. It pays attention to media
types and automatically engages transcoding if needed. The order of
media sections of different types can be differend between the call legs
that are being connected. Subsequent reinvites will produce SDPs with
the media sections in the correct order.

Change-Id: I40c3363997de169edc553733d52acdfd9f0181ad
pull/1897/head
Richard Fuchs 4 months ago
parent 73d4195b3c
commit bce7dcf05f

@ -3747,6 +3747,66 @@ int monologue_unsubscribe(struct call_monologue *dst_ml, sdp_ng_flags *flags) {
}
__attribute__((nonnull(1, 2, 3)))
void dialogue_connect(struct call_monologue *src_ml, struct call_monologue *dst_ml, sdp_ng_flags *flags) {
// for each source media, find a usable destination media
for (unsigned int i = 0; i < src_ml->medias->len; i++) {
__auto_type src_media = src_ml->medias->pdata[i];
if (!src_media)
continue;
struct call_media *dst_media = NULL;
// try a=mid first if there is one
if (src_media->media_id.len) {
dst_media = t_hash_table_lookup(dst_ml->media_ids, &src_media->media_id);
// type must still match
if (str_cmp_str(&dst_media->type, &src_media->type))
dst_media = NULL;
}
// otherwise try by index
if (!dst_media) {
for (unsigned int j = 0; j < dst_ml->medias->len; j++) {
unsigned int dx = (j + i) % dst_ml->medias->len;
dst_media = dst_ml->medias->pdata[dx];
if (!dst_media)
continue;
// if type matches, we can connect
if (!str_cmp_str(&dst_media->type, &src_media->type))
break;
dst_media = NULL;
}
}
// anything found?
if (!dst_media) {
ilog(LOG_WARN, "Unable to find usable media (type '" STR_FORMAT "') to connect call",
STR_FMT(&src_media->type));
continue;
}
__media_unconfirm(src_media, "connect");
__media_unconfirm(dst_media, "connect");
g_auto(medias_q) medias = TYPED_GQUEUE_INIT;
__subscribe_medias_both_ways(src_media, dst_media, false, &medias);
__medias_unconfirm(&medias, "connect");
codec_handlers_update(src_media, dst_media,
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
codec_handlers_update(dst_media, src_media,
.allow_asymmetric = !!flags->allow_asymmetric_codecs);
__update_init_subscribers(src_media, NULL, NULL, flags->opmode);
__update_init_subscribers(dst_media, NULL, NULL, flags->opmode);
__update_init_medias(&medias, flags->opmode);
}
}
static int __rtp_stats_sort(const void *ap, const void *bp) {

@ -848,6 +848,7 @@ int monologue_subscribe_request(const subscription_q *srms, struct call_monologu
int monologue_subscribe_answer(struct call_monologue *dst, sdp_ng_flags *flags,
sdp_streams_q *streams);
int monologue_unsubscribe(struct call_monologue *dst, sdp_ng_flags *);
void dialogue_connect(struct call_monologue *, struct call_monologue *, sdp_ng_flags *);
void monologue_destroy(struct call_monologue *ml);
int call_delete_branch_by_id(const str *callid, const str *branch,
const str *fromtag, const str *totag, ng_command_ctx_t *, int delete_delay);

Loading…
Cancel
Save