mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	app_page: Add predial handlers for app_page.
(closes issue AFS-14) Review: https://reviewboard.asterisk.org/r/3045/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@403576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		
							
								
								
									
										10
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -12,6 +12,9 @@ | ||||
| --- Functionality changes from Asterisk 12 to Asterisk 13 -------------------- | ||||
| ------------------------------------------------------------------------------ | ||||
|  | ||||
| Applications | ||||
| -------------------------- | ||||
|  | ||||
| ConfBridge | ||||
| -------------------------- | ||||
|  * CONFBRIDGE dialplan function is now capable of creating/modifying dynamic | ||||
| @@ -42,9 +45,14 @@ Directory | ||||
|      USEREXIT    user pressed '#' from the selection prompt to exit | ||||
|      FAILED      directory failed in a way that wasn't accounted for. Dang. | ||||
|  | ||||
| Page | ||||
| -------------------------- | ||||
|  * Added options 'b' and 'B' to apply predial handlers for outgoing calls | ||||
|    and for the channel executing Page respectively. | ||||
|  | ||||
| PickupChan | ||||
| -------------------------- | ||||
| * PickupChan now accepts channel uniqueids of channels to pickup. | ||||
|  * PickupChan now accepts channel uniqueids of channels to pickup. | ||||
|  | ||||
| Say | ||||
| -------------------------- | ||||
|   | ||||
| @@ -65,6 +65,27 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| 			</parameter> | ||||
| 			<parameter name="options"> | ||||
| 				<optionlist> | ||||
| 				<option name="b" argsep="^"> | ||||
| 					<para>Before initiating an outgoing call, Gosub to the specified | ||||
| 					location using the newly created channel.  The Gosub will be | ||||
| 					executed for each destination channel.</para> | ||||
| 					<argument name="context" required="false" /> | ||||
| 					<argument name="exten" required="false" /> | ||||
| 					<argument name="priority" required="true" hasparams="optional" argsep="^"> | ||||
| 						<argument name="arg1" multiple="true" required="true" /> | ||||
| 						<argument name="argN" /> | ||||
| 					</argument> | ||||
| 				</option> | ||||
| 				<option name="B" argsep="^"> | ||||
| 					<para>Before initiating the outgoing call(s), Gosub to the specified | ||||
| 					location using the current channel.</para> | ||||
| 					<argument name="context" required="false" /> | ||||
| 					<argument name="exten" required="false" /> | ||||
| 					<argument name="priority" required="true" hasparams="optional" argsep="^"> | ||||
| 						<argument name="arg1" multiple="true" required="true" /> | ||||
| 						<argument name="argN" /> | ||||
| 					</argument> | ||||
| 				</option> | ||||
| 					<option name="d"> | ||||
| 						<para>Full duplex audio</para> | ||||
| 					</option> | ||||
| @@ -118,14 +139,20 @@ enum page_opt_flags { | ||||
| 	PAGE_IGNORE_FORWARDS = (1 << 4), | ||||
| 	PAGE_ANNOUNCE = (1 << 5), | ||||
| 	PAGE_NOCALLERANNOUNCE = (1 << 6), | ||||
| 	PAGE_PREDIAL_CALLEE = (1 << 7), | ||||
| 	PAGE_PREDIAL_CALLER = (1 << 8), | ||||
| }; | ||||
|  | ||||
| enum { | ||||
| 	OPT_ARG_ANNOUNCE = 0, | ||||
| 	OPT_ARG_ARRAY_SIZE = 1, | ||||
| 	OPT_ARG_PREDIAL_CALLEE = 1, | ||||
| 	OPT_ARG_PREDIAL_CALLER = 2, | ||||
| 	OPT_ARG_ARRAY_SIZE = 3, | ||||
| }; | ||||
|  | ||||
| AST_APP_OPTIONS(page_opts, { | ||||
| 	AST_APP_OPTION_ARG('b', PAGE_PREDIAL_CALLEE, OPT_ARG_PREDIAL_CALLEE), | ||||
| 	AST_APP_OPTION_ARG('B', PAGE_PREDIAL_CALLER, OPT_ARG_PREDIAL_CALLER), | ||||
| 	AST_APP_OPTION('d', PAGE_DUPLEX), | ||||
| 	AST_APP_OPTION('q', PAGE_QUIET), | ||||
| 	AST_APP_OPTION('r', PAGE_RECORD), | ||||
| @@ -283,6 +310,12 @@ static int page_exec(struct ast_channel *chan, const char *data) | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLER) | ||||
| 		&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLER])) { | ||||
| 		ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLER]); | ||||
| 		ast_app_exec_sub(NULL, chan, options.opts[OPT_ARG_PREDIAL_CALLER], 0); | ||||
| 	} | ||||
|  | ||||
| 	/* Go through parsing/calling each device */ | ||||
| 	while ((tech = strsep(&args.devices, "&"))) { | ||||
| 		int state = 0; | ||||
| @@ -327,6 +360,11 @@ static int page_exec(struct ast_channel *chan, const char *data) | ||||
| 		/* Set ANSWER_EXEC as global option */ | ||||
| 		ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts); | ||||
|  | ||||
| 		if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE) | ||||
| 			&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) { | ||||
| 			ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, options.opts[OPT_ARG_PREDIAL_CALLEE]); | ||||
| 		} | ||||
|  | ||||
| 		if (timeout) { | ||||
| 			ast_dial_set_global_timeout(dial, timeout * 1000); | ||||
| 		} | ||||
|   | ||||
| @@ -44,6 +44,7 @@ enum ast_dial_option { | ||||
| 	AST_DIAL_OPTION_ANSWER_EXEC,             /*!< Execute application upon answer in async mode */ | ||||
| 	AST_DIAL_OPTION_MUSIC,                   /*!< Play music on hold instead of ringing to the calling channel */ | ||||
| 	AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, /*!< Disable call forwarding on channels */ | ||||
| 	AST_DIAL_OPTION_PREDIAL,                 /*!< Execute a predial subroutine before dialing */ | ||||
| 	AST_DIAL_OPTION_MAX,                     /*!< End terminator -- must always remain last */ | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										55
									
								
								main/dial.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								main/dial.c
									
									
									
									
									
								
							| @@ -145,6 +145,22 @@ static int music_disable(void *data) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void *predial_enable(void *data) | ||||
| { | ||||
| 	return ast_strdup(data); | ||||
| } | ||||
|  | ||||
| static int predial_disable(void *data) | ||||
| { | ||||
| 	if (!data) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	ast_free(data); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /*! \brief Application execution function for 'ANSWER_EXEC' option */ | ||||
| static void answer_exec_run(struct ast_dial *dial, struct ast_dial_channel *dial_channel, char *app, char *args) | ||||
| { | ||||
| @@ -186,6 +202,7 @@ static const struct ast_option_types option_types[] = { | ||||
| 	{ AST_DIAL_OPTION_ANSWER_EXEC, answer_exec_enable, answer_exec_disable }, /*!< Execute application upon answer in async mode */ | ||||
| 	{ AST_DIAL_OPTION_MUSIC, music_enable, music_disable },                   /*!< Play music to the caller instead of ringing */ | ||||
| 	{ AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL, NULL },                  /*!< Disable call forwarding on channels */ | ||||
| 	{ AST_DIAL_OPTION_PREDIAL, predial_enable, predial_disable },             /*!< Execute a subroutine on the outbound channels prior to dialing */ | ||||
| 	{ AST_DIAL_OPTION_MAX, NULL, NULL },                                      /*!< Terminator of list */ | ||||
| }; | ||||
|  | ||||
| @@ -259,7 +276,7 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device) | ||||
| } | ||||
|  | ||||
| /*! \brief Helper function that requests all channels */ | ||||
| static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap) | ||||
| static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channel *chan, struct ast_format_cap *cap, const char *predial_string) | ||||
| { | ||||
| 	char numsubst[AST_MAX_EXTENSION]; | ||||
| 	struct ast_format_cap *cap_all_audio = NULL; | ||||
| @@ -316,6 +333,17 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe | ||||
|  | ||||
| 	ast_channel_stage_snapshot_done(channel->owner); | ||||
|  | ||||
| 	if (!ast_strlen_zero(predial_string)) { | ||||
| 		const char *predial_callee = ast_app_expand_sub_args(chan, predial_string); | ||||
| 		if (!predial_callee) { | ||||
| 			ast_log(LOG_ERROR, "Could not expand subroutine arguments in predial request '%s'\n", predial_string); | ||||
| 		} | ||||
| 		ast_autoservice_start(chan); | ||||
| 		ast_pre_call(channel->owner, predial_callee); | ||||
| 		ast_autoservice_stop(chan); | ||||
| 		ast_free((char *) predial_callee); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -323,10 +351,15 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_ | ||||
| { | ||||
| 	struct ast_dial_channel *channel; | ||||
| 	int res = -1; | ||||
| 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL]; | ||||
|  | ||||
| 	if (!ast_strlen_zero(predial_string)) { | ||||
| 		ast_replace_subargument_delimiter(predial_string); | ||||
| 	} | ||||
|  | ||||
| 	AST_LIST_LOCK(&dial->channels); | ||||
| 	AST_LIST_TRAVERSE(&dial->channels, channel, list) { | ||||
| 		if ((res = begin_dial_prerun(channel, chan, cap))) { | ||||
| 		if ((res = begin_dial_prerun(channel, chan, cap, predial_string))) { | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| @@ -336,13 +369,13 @@ int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_ | ||||
| } | ||||
|  | ||||
| /*! \brief Helper function that does the beginning dialing per-appended channel */ | ||||
| static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async) | ||||
| static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_channel *chan, int async, const char *predial_string) | ||||
| { | ||||
| 	char numsubst[AST_MAX_EXTENSION]; | ||||
| 	int res = 1; | ||||
|  | ||||
| 	/* If no owner channel exists yet execute pre-run */ | ||||
| 	if (!channel->owner && begin_dial_prerun(channel, chan, NULL)) { | ||||
| 	if (!channel->owner && begin_dial_prerun(channel, chan, NULL, predial_string)) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| @@ -371,11 +404,16 @@ static int begin_dial(struct ast_dial *dial, struct ast_channel *chan, int async | ||||
| { | ||||
| 	struct ast_dial_channel *channel = NULL; | ||||
| 	int success = 0; | ||||
| 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL]; | ||||
|  | ||||
| 	if (!ast_strlen_zero(predial_string)) { | ||||
| 		ast_replace_subargument_delimiter(predial_string); | ||||
| 	} | ||||
|  | ||||
| 	/* Iterate through channel list, requesting and calling each one */ | ||||
| 	AST_LIST_LOCK(&dial->channels); | ||||
| 	AST_LIST_TRAVERSE(&dial->channels, channel, list) { | ||||
| 		success += begin_dial_channel(channel, chan, async); | ||||
| 		success += begin_dial_channel(channel, chan, async, predial_string); | ||||
| 	} | ||||
| 	AST_LIST_UNLOCK(&dial->channels); | ||||
|  | ||||
| @@ -389,6 +427,11 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c | ||||
| 	struct ast_channel *original = channel->owner; | ||||
| 	char *tmp = ast_strdupa(ast_channel_call_forward(channel->owner)); | ||||
| 	char *tech = "Local", *device = tmp, *stuff; | ||||
| 	char *predial_string = dial->options[AST_DIAL_OPTION_PREDIAL]; | ||||
|  | ||||
| 	if (!ast_strlen_zero(predial_string)) { | ||||
| 		ast_replace_subargument_delimiter(predial_string); | ||||
| 	} | ||||
|  | ||||
| 	/* If call forwarding is disabled just drop the original channel and don't attempt to dial the new one */ | ||||
| 	if (FIND_RELATIVE_OPTION(dial, channel, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING)) { | ||||
| @@ -428,7 +471,7 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c | ||||
| 	channel->owner = NULL; | ||||
|  | ||||
| 	/* Finally give it a go... send it out into the world */ | ||||
| 	begin_dial_channel(channel, chan, chan ? 0 : 1); | ||||
| 	begin_dial_channel(channel, chan, chan ? 0 : 1, predial_string); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user