mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +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)); | ||||||
|  |  | ||||||
| 		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); | 		ast_channel_unlock(chan); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user