MT#55283 store original call ID in monologue

Change-Id: If6260904f2fa2c4cd87a9acc42a7c930c4ef6492
pull/2127/head
Richard Fuchs 1 week ago
parent e89fddb524
commit 183aaaec80

@ -5875,13 +5875,14 @@ call_t *call_get_opmode(const str *callid, enum ng_opmode opmode) {
*
* Must be called with call->master_lock held in W.
*/
struct call_monologue *__monologue_create(call_t *call) {
struct call_monologue *__monologue_create(call_t *call, const str *callid) {
struct call_monologue *ret;
dbg_int("creating new monologue");
ret = uid_alloc(&call->monologues);
ret->call = call;
ret->call_id = call_str_cpy(callid);
ret->created_us = rtpe_now;
ret->associated_tags = g_hash_table_new(g_direct_hash, g_direct_equal);
ret->medias = medias_arr_new();
@ -6139,10 +6140,10 @@ static struct call_monologue *call_get_monologue_alias(call_t *call, const str *
*
* Must be called with call->master_lock held in W.
*/
struct call_monologue *call_get_or_create_monologue(call_t *call, const str *fromtag) {
struct call_monologue *call_get_or_create_monologue(call_t *call, const str *callid, const str *fromtag) {
struct call_monologue *ret = call_get_monologue(call, fromtag);
if (!ret) {
ret = __monologue_create(call);
ret = __monologue_create(call, callid);
__monologue_tag(ret, fromtag);
}
return ret;
@ -6190,7 +6191,10 @@ static bool call_monologues_associations_left(call_t * c) {
*
* `dialogue` must be initialised to zero.
*/
static int call_get_monologue_new(struct call_monologue *monologues[2], call_t *call,
__attribute__((nonnull(1, 2, 3, 4)))
static int call_get_monologue_new(struct call_monologue *monologues[2],
call_t *call,
const str *callid,
const str *fromtag,
const str *totag,
const str *viabranch,
@ -6204,7 +6208,7 @@ static int call_get_monologue_new(struct call_monologue *monologues[2], call_t *
ret = call_get_monologue_alias(call, fromtag, flags, &flags->sdp, ep);
if (!ret) {
/* this is a brand new offer */
ret = __monologue_create(call);
ret = __monologue_create(call, callid);
__monologue_tag(ret, fromtag);
goto new_branch;
}
@ -6238,7 +6242,7 @@ static int call_get_monologue_new(struct call_monologue *monologues[2], call_t *
* another monologue without to-tag (to be filled in later) */
new_branch:
dbg_int("create new \"other side\" monologue for viabranch "STR_FORMAT, STR_FMT0(viabranch));
os = __monologue_create(call);
os = __monologue_create(call, callid);
__monologue_viabranch(os, viabranch);
goto finish;
@ -6282,7 +6286,10 @@ finish:
*
* `dialogue` must be initialised to zero.
*/
static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call,
__attribute__((nonnull(1, 2, 3, 4)))
static int call_get_dialogue(struct call_monologue *monologues[2],
call_t *call,
const str *callid,
const str *fromtag,
const str *totag,
const str *viabranch,
@ -6290,7 +6297,7 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call,
{
struct call_monologue *ft, *tt;
dbg_int("getting dialogue for tags '"STR_FORMAT"'<>'"STR_FORMAT"' in call '"STR_FORMAT"'",
dbg_int("getting dialogue for tags '" STR_FORMAT "'<>'" STR_FORMAT "' in call '" STR_FORMAT "'",
STR_FMT(fromtag), STR_FMT(totag), STR_FMT(&call->callid));
/* ft - is always this side's tag (in offer it's message's from-tag, in answer it's message's to-tag)
@ -6300,7 +6307,7 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *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(monologues, call, fromtag, totag, viabranch, flags, ep);
return call_get_monologue_new(monologues, call, callid, fromtag, totag, viabranch, flags, ep);
/* if the from-tag is known already, return that */
ft = call_get_monologue_alias(call, fromtag, flags, &flags->sdp, ep);
@ -6353,14 +6360,14 @@ static int call_get_dialogue(struct call_monologue *monologues[2], call_t *call,
* hence `ft->tag` has to be empty at this stage.
*/
if (!ft)
ft = __monologue_create(call);
ft = __monologue_create(call, callid);
else if (ft->tag.s) {
// Allow an updated/changed to-tag in answers unless the flag to
// suppress this feature is set. A changed to-tag will be stored
// as a tag alias.
if (!flags || flags->opmode != OP_ANSWER || flags->new_branch
|| (ML_ISSET(ft, FINAL_RESPONSE) && !flags->provisional))
ft = __monologue_create(call);
ft = __monologue_create(call, callid);
}
tag_setup:
@ -6388,7 +6395,9 @@ done:
/* 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_monologue *monologues[2], call_t *call,
int call_get_mono_dialogue(struct call_monologue *monologues[2],
call_t *call,
const str *callid,
const str *fromtag,
const str *totag,
const str *viabranch,
@ -6396,9 +6405,9 @@ int call_get_mono_dialogue(struct call_monologue *monologues[2], call_t *call,
{
/* initial offer */
if (!totag || !totag->s)
return call_get_monologue_new(monologues, call, fromtag, NULL, viabranch, flags, ep);
return call_get_monologue_new(monologues, call, callid, fromtag, NULL, viabranch, flags, ep);
return call_get_dialogue(monologues, call, fromtag, totag, viabranch, flags, ep);
return call_get_dialogue(monologues, call, callid, fromtag, totag, viabranch, flags, ep);
}
static void media_stop(struct call_media *m) {

@ -180,7 +180,7 @@ static str call_update_lookup_udp(char **out, enum ng_opmode opmode, const char*
updated_created_from(c, addr);
if (call_get_mono_dialogue(monologues, c, &fromtag, &totag, NULL, NULL, NULL))
if (call_get_mono_dialogue(monologues, c, &callid, &fromtag, &totag, NULL, NULL, NULL))
goto ml_fail;
struct call_monologue *from_ml = monologues[0];
@ -339,7 +339,7 @@ static str call_request_lookup_tcp(char **out, enum ng_opmode opmode) {
str_swap(&fromtag, &totag);
}
if (call_get_mono_dialogue(monologues, c, &fromtag, &totag, NULL, NULL, NULL)) {
if (call_get_mono_dialogue(monologues, c, &callid, &fromtag, &totag, NULL, NULL, NULL)) {
ilog(LOG_WARNING, "Invalid dialogue association");
goto out2;
}
@ -621,7 +621,7 @@ static const char *call_offer_answer_ng(ng_command_ctx_t *ctx, const char *addr)
call_ngb_hold_ref(call, ctx->ngbuf);
errstr = "Invalid dialogue association";
if (call_get_mono_dialogue(monologues, call, &flags.from_tag, &flags.to_tag,
if (call_get_mono_dialogue(monologues, call, &flags.call_id, &flags.from_tag, &flags.to_tag,
flags.via_branch.s ? &flags.via_branch : NULL, &flags,
streams.length ? &streams.head->data->rtp_endpoint : NULL)) {
goto out;
@ -2121,7 +2121,7 @@ const char *call_publish_ng(ng_command_ctx_t *ctx, const char *addr) {
return NULL;
updated_created_from(call, addr);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.from_tag);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.call_id, &flags.from_tag);
ret = monologue_publish(ml, &streams, &flags);
if (ret)
@ -2191,7 +2191,7 @@ const char *call_subscribe_request_ng(ng_command_ctx_t *ctx) {
g_autoptr(call_t) call = t_queue_pop_head(&calls);
struct call_monologue *dest_ml = call_get_or_create_monologue(call, &flags.to_tag);
struct call_monologue *dest_ml = call_get_or_create_monologue(call, &flags.call_id, &flags.to_tag);
int ret = monologue_subscribe_request(&mq, dest_ml, &flags);
if (ret)
@ -2430,7 +2430,7 @@ const char *call_connect_ng(ng_command_ctx_t *ctx) {
if (!call)
return "Failed to merge two calls into one (tag collision)";
struct call_monologue *dest_ml = call_get_or_create_monologue(call, &flags.to_tag);
struct call_monologue *dest_ml = call_get_or_create_monologue(call, &flags.call_id, &flags.to_tag);
if (!dest_ml)
return "To-tag not found";
@ -2496,7 +2496,7 @@ const char *call_transform_ng(ng_command_ctx_t *ctx) {
flags.from_tag = STR_LEN(rand_hex_str(rand_from_tag, 32), 64);
call = call_get_or_create(&flags.call_id, false);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.from_tag);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.call_id, &flags.from_tag);
g_auto(medias_q) mq = TYPED_GQUEUE_INIT;
if (!monologue_transform(ml, &flags, &mq))
@ -2546,7 +2546,7 @@ const char *call_create_ng(ng_command_ctx_t *ctx) {
flags.from_tag = STR_LEN(rand_hex_str(rand_from_tag, 32), 64);
call = call_get_or_create(&flags.call_id, false);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.from_tag);
struct call_monologue *ml = call_get_or_create_monologue(call, &flags.call_id, &flags.from_tag);
if (!monologue_call_create(ml, &flags))
return "failed to set up call/monologue";

@ -648,7 +648,7 @@ static const char *__make_transform_handler(struct codec_handler *handler) {
// create dedicated monologue and dedicated call_media to send media to the
// remote rtpengine and forward received media to its designated destination
tfh->transform_ml = call_get_or_create_monologue(call, STR_PTR("transform handler"));
tfh->transform_ml = call_get_or_create_monologue(call, &ml->call_id, STR_PTR("transform handler"));
tfh->transform_media = call_make_transform_media(tfh->transform_ml, &media->type, media->type_id,
&STR_NULL, &tcc->transform, &tcc->local_interface);

@ -115,14 +115,19 @@ static uint64_t jr_str_int(JsonReader *r) {
}
static struct call_monologue *janus_get_monologue(uint64_t handle_id, call_t *call,
struct call_monologue *(*fn)(call_t *, const str *))
static struct call_monologue *janus_call_get_monologue(call_t *c, const str *callid, const str *tag) {
return call_get_monologue(c, tag);
}
static struct call_monologue *janus_get_monologue(uint64_t handle_id, call_t *call, const str *callid,
struct call_monologue *(*fn)(call_t *, const str *, const str *))
{
g_autoptr(char) handle_buf = NULL;
handle_buf = g_strdup_printf("%" PRIu64, handle_id);
str handle_str = STR(handle_buf);
return fn(call, &handle_str);
return fn(call, callid, &handle_str);
}
@ -404,7 +409,8 @@ static void janus_publishers_list(JsonBuilder *builder, call_t *call, struct jan
continue;
// get monologue
struct call_monologue *ml = janus_get_monologue(*handle_id_ptr, call, call_get_monologue);
struct call_monologue *ml = janus_get_monologue(*handle_id_ptr, call, NULL,
janus_call_get_monologue);
if (!ml)
continue;
@ -437,7 +443,7 @@ static const char *janus_videoroom_join_sub(struct janus_handle *handle, struct
t_hash_table_insert(room->subscribers, uint64_dup(handle->id), uint64_dup(feed_id));
// add the subscription
struct call_monologue *source_ml = janus_get_monologue(*feed_handle, call, call_get_monologue);
struct call_monologue *source_ml = janus_get_monologue(*feed_handle, call, NULL, janus_call_get_monologue);
if (!source_ml)
return "Feed not found";
@ -616,7 +622,7 @@ static const char *janus_videoroom_join(struct websocket_message *wm, struct jan
if (!medias.length)
return "No feeds to subscribe to given";
struct call_monologue *dest_ml = janus_get_monologue(handle->id, call,
struct call_monologue *dest_ml = janus_get_monologue(handle->id, call, &room->call_id,
call_get_or_create_monologue);
g_auto(sdp_ng_flags) flags;
@ -856,7 +862,7 @@ static const char *janus_videoroom_configure(struct websocket_message *wm, struc
if (!sdp_streams(&parsed, &streams, &flags))
return "Incomplete SDP specification";
ml = janus_get_monologue(handle->id, call, call_get_or_create_monologue);
ml = janus_get_monologue(handle->id, call, &room->call_id, call_get_or_create_monologue);
// accept unsupported codecs if necessary
flags.accept_any = 1;
@ -885,7 +891,7 @@ static const char *janus_videoroom_configure(struct websocket_message *wm, struc
}
else {
// reconfigure existing publisher
ml = janus_get_monologue(handle->id, call, call_get_monologue);
ml = janus_get_monologue(handle->id, call, NULL, janus_call_get_monologue);
if (!ml)
return "Not an existing publisher";
}
@ -980,12 +986,12 @@ static const char *janus_videoroom_start(struct websocket_message *wm, struct ja
if (!feed_handle)
return "No such feed exists";
struct call_monologue *source_ml = janus_get_monologue(*feed_handle, call, call_get_monologue);
struct call_monologue *source_ml = janus_get_monologue(*feed_handle, call, NULL, janus_call_get_monologue);
if (!source_ml)
return "Feed not found";
// XXX verify that dest_ml is subscribed to source_ml
struct call_monologue *dest_ml = janus_get_monologue(handle->id, call, call_get_monologue);
struct call_monologue *dest_ml = janus_get_monologue(handle->id, call, NULL, janus_call_get_monologue);
if (!dest_ml)
return "Subscriber not found";
@ -1041,7 +1047,7 @@ static const char *janus_videoroom_unpublish(struct websocket_message *wm, struc
// notify other publishers
janus_notify_publishers(room_id, handle->id, NULL, *feed_id, janus_notify_publishers_unpublished);
struct call_monologue *ml = janus_get_monologue(handle->id, call, call_get_monologue);
struct call_monologue *ml = janus_get_monologue(handle->id, call, NULL, janus_call_get_monologue);
if (ml)
monologue_destroy(ml);
@ -1360,7 +1366,7 @@ static void janus_destroy_handle(struct janus_handle *handle) {
call_t *call = call_get(&room->call_id);
if (call) {
// remove publisher monologue
struct call_monologue *ml = janus_get_monologue(handle_id, call, call_get_monologue);
struct call_monologue *ml = janus_get_monologue(handle_id, call, NULL, janus_call_get_monologue);
if (ml)
monologue_destroy(ml);
@ -1377,7 +1383,7 @@ static void janus_destroy_handle(struct janus_handle *handle) {
call_t *call = call_get(&room->call_id);
if (call) {
// remove subscriber monologue
struct call_monologue *ml = janus_get_monologue(handle_id, call, call_get_monologue);
struct call_monologue *ml = janus_get_monologue(handle_id, call, NULL, janus_call_get_monologue);
if (ml)
monologue_destroy(ml);

@ -1557,7 +1557,7 @@ static int redis_tags(call_t *c, struct redis_list *tags, parser_arg arg) {
for (i = 0; i < tags->len; i++) {
rh = &tags->rh[i];
ml = __monologue_create(c);
ml = __monologue_create(c, &c->callid);
if (!ml)
return -1;
@ -1565,6 +1565,8 @@ static int redis_tags(call_t *c, struct redis_list *tags, parser_arg arg) {
return -1;
if (!redis_hash_get_str(&s, rh, "tag"))
__monologue_tag(ml, &s);
if (!redis_hash_get_str(&s, rh, "call_id"))
ml->call_id = call_str_cpy(&s);
if (!redis_hash_get_str(&s, rh, "via-branch"))
__monologue_viabranch(ml, &s);
if (!redis_hash_get_str(&s, rh, "label"))
@ -2639,6 +2641,8 @@ static str redis_encode_json(ng_parser_ctx_t *ctx, call_t *c, void **to_free) {
if (ml->tag.s)
JSON_SET_SIMPLE_STR("tag", &ml->tag);
if (ml->call_id.s)
JSON_SET_SIMPLE_STR("call_id", &ml->tag);
if (ml->viabranch.s)
JSON_SET_SIMPLE_STR("via-branch", &ml->viabranch);
if (ml->label.s)

@ -602,7 +602,8 @@ TYPED_GPTRARRAY(medias_arr, struct call_media)
* A regular A/B call has two call_monologue objects with each subscribed to the other.
*/
struct call_monologue {
call_t *call; /* RO */
call_t *call; /* RO */
str call_id; // RO - in case of merged calls with ID aliases
unsigned int unique_id; /* RO */
str tag;
@ -838,7 +839,9 @@ extern __thread call_t *call_memory_arena;
int call_init(void);
void call_free(void);
struct call_monologue *__monologue_create(call_t *call);
__attribute__((nonnull(1, 2)))
struct call_monologue *__monologue_create(call_t *call, const str *callid);
void __monologue_free(struct call_monologue *m);
void __monologue_tag(struct call_monologue *ml, const str *tag);
void __monologue_viabranch(struct call_monologue *ml, const str *viabranch);
@ -874,16 +877,25 @@ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(subscription_q, media_subscriptions_clear)
call_t *call_get_or_create(const str *callid, bool exclusive);
call_t *call_get_opmode(const str *callid, enum ng_opmode opmode);
void call_make_own_foreign(call_t *c, bool foreign);
int call_get_mono_dialogue(struct call_monologue *monologues[2], call_t *call,
__attribute__((nonnull(1, 2, 3, 4)))
int call_get_mono_dialogue(struct call_monologue *monologues[2],
call_t *call,
const str *callid,
const str *fromtag,
const str *totag,
const str *viabranch,
sdp_ng_flags *, const endpoint_t *);
struct call_monologue *call_get_monologue(call_t *call, const str *fromtag);
struct call_monologue *call_get_or_create_monologue(call_t *call, const str *fromtag);
__attribute__((nonnull(1, 2, 3)))
struct call_monologue *call_get_or_create_monologue(call_t *call, const str *callid, const str *fromtag);
__attribute__((nonnull(1, 2, 4, 5, 6)))
struct call_media *call_make_transform_media(struct call_monologue *ml, const str *type, enum media_type type_id,
const str *media_id, const endpoint_t *remote, const str *interface);
__attribute__((nonnull(1)))
call_t *call_get(const str *callid);
__attribute__((nonnull(1)))

@ -5257,9 +5257,9 @@ int main(void) {
const str callid1 = STR_CONST("test1");
const str callid2 = STR_CONST("test2");
call_t *call1 = call_get_or_create(&callid1, true);
struct call_monologue *ml1 = call_get_or_create_monologue(call1, &callid1);
struct call_monologue *ml1 = call_get_or_create_monologue(call1, &callid1, &callid1);
call_t *call2 = call_get_or_create(&callid2, true);
struct call_monologue *ml2 = call_get_or_create_monologue(call2, &callid2);
struct call_monologue *ml2 = call_get_or_create_monologue(call2, &callid2, &callid2);
call1->created = ml1->started = 157 * 1000000LL;
call2->created = ml2->started = 57 * 1000000LL;

@ -101,8 +101,8 @@ static void __start(const char *file, int line) {
call.callid = STR("test-call");
bencode_buffer_init(&call.buffer);
call_memory_arena_set(&call);
ml_A = __monologue_create(&call);
ml_B = __monologue_create(&call);
ml_A = __monologue_create(&call, &call.callid);
ml_B = __monologue_create(&call, &call.callid);
media_A = call_media_new(&call); // originator
media_B = call_media_new(&call); // output destination
t_queue_push_tail(&media_A->streams, ps_new(media_A));

Loading…
Cancel
Save