mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -242,6 +242,10 @@
 | 
				
			|||||||
					<para>Asterisk will ignore any connected line update requests or any redirecting party
 | 
										<para>Asterisk will ignore any connected line update requests or any redirecting party
 | 
				
			||||||
					update requests it may receive on this dial attempt.</para>
 | 
										update requests it may receive on this dial attempt.</para>
 | 
				
			||||||
				</option>
 | 
									</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">
 | 
									<option name="k">
 | 
				
			||||||
					<para>Allow the called party to enable parking of the call by sending
 | 
										<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>
 | 
										the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
 | 
				
			||||||
@@ -750,6 +754,7 @@ enum {
 | 
				
			|||||||
#define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
 | 
					#define OPT_RING_WITH_EARLY_MEDIA (1LLU << 43)
 | 
				
			||||||
#define OPT_HANGUPCAUSE      (1LLU << 44)
 | 
					#define OPT_HANGUPCAUSE      (1LLU << 44)
 | 
				
			||||||
#define OPT_HEARPULSING      (1LLU << 45)
 | 
					#define OPT_HEARPULSING      (1LLU << 45)
 | 
				
			||||||
 | 
					#define OPT_TOPOLOGY_PRESERVE (1LLU << 46)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
	OPT_ARG_ANNOUNCE = 0,
 | 
						OPT_ARG_ANNOUNCE = 0,
 | 
				
			||||||
@@ -795,6 +800,7 @@ AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
 | 
				
			|||||||
	AST_APP_OPTION('H', OPT_CALLER_HANGUP),
 | 
						AST_APP_OPTION('H', OPT_CALLER_HANGUP),
 | 
				
			||||||
	AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
 | 
						AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
 | 
				
			||||||
	AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
 | 
						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_CALLEE_PARK),
 | 
				
			||||||
	AST_APP_OPTION('K', OPT_CALLER_PARK),
 | 
						AST_APP_OPTION('K', OPT_CALLER_PARK),
 | 
				
			||||||
	AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
 | 
						AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
 | 
				
			||||||
@@ -855,6 +861,16 @@ struct chanlist {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
AST_LIST_HEAD_NOLOCK(dial_head, 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 int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void chanlist_free(struct chanlist *outgoing)
 | 
					static void chanlist_free(struct chanlist *outgoing)
 | 
				
			||||||
@@ -2389,6 +2405,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	struct ast_party_caller caller;
 | 
						struct ast_party_caller caller;
 | 
				
			||||||
	int max_forwards;
 | 
						int max_forwards;
 | 
				
			||||||
 | 
						struct ast_datastore *topology_ds = NULL;
 | 
				
			||||||
	SCOPE_ENTER(1, "%s: Data: %s\n", ast_channel_name(chan), data);
 | 
						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). */
 | 
						/* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
 | 
				
			||||||
@@ -2690,7 +2707,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));
 | 
							ast_party_connected_line_copy(&tmp->connected, ast_channel_connected(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));
 | 
								topology = ast_stream_topology_clone(ast_channel_get_stream_topology(chan));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ast_channel_unlock(chan);
 | 
							ast_channel_unlock(chan);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user