diff --git a/README.md b/README.md index 389707de4..e63a9a059 100644 --- a/README.md +++ b/README.md @@ -695,7 +695,7 @@ Optionally included keys are: back in logs and statistics output. For some commands (e.g. `block media`) the given label is not used to set the label of the call participant, but rather to select an existing call participant. -* `set-label` or `to-label` +* `set-label` Some commands (e.g. `block media`) use the given `label` to select an existing call participant. For these commands, `set-label` instead @@ -703,6 +703,15 @@ Optionally included keys are: the selected call participant (if selected via `from-tag`) or for the newly created participant (e.g. for `subscribe request`). +* `to-label` + + Commands that allow selection of two call participants (e.g. `block + media`) can use `label` instead of `from-tag` to select the first call + participant. The `to-label` can then be used instead of `to-tag` to + select the other call participant. + + For `subscribe request` the `to-label` is synonymous with `set-label`. + * `flags` The value of the `flags` key is a list. The list contains zero or more of the following strings. @@ -2014,7 +2023,7 @@ block media for just a single media flow. This is relevant to scenarios that involve forked media that were established with one or more `subscribe request`. To select just one media flow for media blocking, in addition to selecting a source call participant as above, a destination call participant -must be specified using the `to-tag` key in the message. +must be specified using the `to-tag` or `to-label`key in the message. `silence media` and `unsilence media` Messages ---------------------------------------------- diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 4c2d7e44b..1d2187b5d 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1105,10 +1105,12 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_ case CSH_LOOKUP("label"): out->label = s; break; - case CSH_LOOKUP("to-label"): case CSH_LOOKUP("set-label"): out->set_label = s; break; + case CSH_LOOKUP("to-label"): + out->to_label = s; + break; case CSH_LOOKUP("address"): out->address = s; break; @@ -2659,6 +2661,7 @@ static const char *call_block_silence_media(bencode_item_t *input, bool on_off, return errstr; if (monologue) { + AUTO_CLEANUP(GQueue sinks, g_queue_clear) = G_QUEUE_INIT; if (flags.to_tag.len) { struct call_monologue *sink = g_hash_table_lookup(call->tags, &flags.to_tag); if (!sink) { @@ -2668,21 +2671,38 @@ static const char *call_block_silence_media(bencode_item_t *input, bool on_off, lcase_verb); return "Media flow not found (to-tag not found)"; } - GList *link = g_hash_table_lookup(monologue->subscribers_ht, sink); - if (!link) { - ilog(LOG_WARN, "Media flow '" STR_FORMAT_M "' -> '" STR_FORMAT_M "' doesn't " - "exist for media %s (to-tag not subscribed)", - STR_FMT_M(&monologue->tag), STR_FMT_M(&flags.to_tag), + g_queue_push_tail(&sinks, sink); + } + else if (flags.to_label.len) { + struct call_monologue *sink = g_hash_table_lookup(call->labels, &flags.to_label); + if (!sink) { + ilog(LOG_WARN, "Media flow '" STR_FORMAT_M "' -> label '" STR_FORMAT "' doesn't " + "exist for media %s (to-label not found)", + STR_FMT_M(&monologue->tag), STR_FMT(&flags.to_label), lcase_verb); - return "Media flow not found (to-tag not subscribed)"; + return "Media flow not found (to-label not found)"; } - struct call_subscription *cs = link->data; + g_queue_push_tail(&sinks, sink); + } + if (sinks.length) { + for (GList *l = sinks.head; l; l = l->next) { + struct call_monologue *sink = l->data; + GList *link = g_hash_table_lookup(monologue->subscribers_ht, sink); + if (!link) { + ilog(LOG_WARN, "Media flow '" STR_FORMAT_M "' -> '" STR_FORMAT_M "' doesn't " + "exist for media %s (to-tag not subscribed)", + STR_FMT_M(&monologue->tag), STR_FMT_M(&flags.to_tag), + lcase_verb); + return "Media flow not found (to-tag not subscribed)"; + } + struct call_subscription *cs = link->data; - ilog(LOG_INFO, "%s directional media flow " - "(tag '" STR_FORMAT_M "' -> '" STR_FORMAT_M "')", - ucase_verb, - STR_FMT_M(&monologue->tag), STR_FMT_M(&sink->tag)); - G_STRUCT_MEMBER(bool, &cs->attrs, attr_offset) = on_off; + ilog(LOG_INFO, "%s directional media flow " + "(tag '" STR_FORMAT_M "' -> '" STR_FORMAT_M "')", + ucase_verb, + STR_FMT_M(&monologue->tag), STR_FMT_M(&sink->tag)); + G_STRUCT_MEMBER(bool, &cs->attrs, attr_offset) = on_off; + } update_init_subscribers(monologue, OP_OTHER); } else { @@ -2999,7 +3019,9 @@ const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *out // the `label=` option was possibly used above to select the from-tag -- // switch it out with `to-label=` or `set-label=` for monologue_subscribe_request // below which sets the label based on `label` for a newly created monologue - flags.label = flags.set_label; + flags.label = flags.to_label; + if (flags.set_label.len) // set-label takes priority + flags.label = flags.set_label; // get destination monologue if (!flags.to_tag.len) { diff --git a/include/call_interfaces.h b/include/call_interfaces.h index bb0592c97..6dfa97677 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -40,6 +40,7 @@ struct sdp_ng_flags { str metadata; str label; str set_label; + str to_label; str address; sockaddr_t xmlrpc_callback; GQueue codec_strip;