app_dial: Add option "j" to preserve initial stream topology of caller

Resolves: #462

UserNote: The option "j" is now available for the Dial application which
uses the initial stream topology of the caller to create the outgoing
channels.

(cherry picked from commit 366dc1e99f)
This commit is contained in:
Maximilian Fridrich
2023-11-30 09:57:56 +01:00
committed by Asterisk Development Team
parent 0f5d624740
commit b3cff31e1a

View File

@@ -242,6 +242,10 @@
<para>Asterisk will ignore any connected line update requests or any redirecting party
update requests it may receive on this dial attempt.</para>
</option>
<option name="j">
<para>Use the initial stream topology of the caller for outgoing channels, even if the caller topology has changed.</para>
<para>NOTE: For this option to work, it has to be present in all invocations of Dial that the caller channel goes through.</para>
</option>
<option name="k">
<para>Allow the called party to enable parking of the call by sending
the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
@@ -705,6 +709,7 @@ enum {
#define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
#define OPT_HANGUPCAUSE (1LLU << 44)
#define OPT_HEARPULSING (1LLU << 45)
#define OPT_TOPOLOGY_PRESERVE (1LLU << 46)
enum {
OPT_ARG_ANNOUNCE = 0,
@@ -749,6 +754,7 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
AST_APP_OPTION('H', OPT_CALLER_HANGUP),
AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
AST_APP_OPTION('j', OPT_TOPOLOGY_PRESERVE),
AST_APP_OPTION('k', OPT_CALLEE_PARK),
AST_APP_OPTION('K', OPT_CALLER_PARK),
AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
@@ -808,6 +814,16 @@ struct chanlist {
AST_LIST_HEAD_NOLOCK(dial_head, chanlist);
static void topology_ds_destroy(void *data) {
struct ast_stream_topology *top = data;
ast_stream_topology_free(top);
}
static const struct ast_datastore_info topology_ds_info = {
.type = "app_dial_topology_preserve",
.destroy = topology_ds_destroy,
};
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode);
static void chanlist_free(struct chanlist *outgoing)
@@ -2326,6 +2342,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
*/
struct ast_party_caller caller;
int max_forwards;
struct ast_datastore *topology_ds = NULL;
SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
/* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
@@ -2627,7 +2644,21 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
*/
ast_party_connected_line_copy(&tmp->connected, ast_channel_connected(chan));
topology = ast_stream_topology_clone(ast_channel_get_stream_topology(chan));
if (ast_test_flag64(&opts, OPT_TOPOLOGY_PRESERVE)) {
topology_ds = ast_channel_datastore_find(chan, &topology_ds_info, NULL);
if (!topology_ds && (topology_ds = ast_datastore_alloc(&topology_ds_info, NULL))) {
topology_ds->data = ast_stream_topology_clone(ast_channel_get_stream_topology(chan));
ast_channel_datastore_add(chan, topology_ds);
}
}
if (topology_ds) {
ao2_ref(topology_ds->data, +1);
topology = topology_ds->data;
} else {
topology = ast_stream_topology_clone(ast_channel_get_stream_topology(chan));
}
ast_channel_unlock(chan);