From 20b8474f20fc387d5b355ee81b751e4988fc28d7 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Mon, 28 Dec 2015 18:18:01 -0700 Subject: main/pbx: Move pbx_builtin dialplan applications to pbx_builtins.c We joked about splitting pbx.c into multiple files but this first step was fairly easy. All of the pbx_builtin dialplan applications have been moved into pbx_builtins.c and a new pbx_private.h file was added. load_pbx_builtins() is called by asterisk.c just after load_pbx(). A few functions were renamed and are cross-exposed between the 2 source files. Change-Id: I87066be3dbf7f5822942ac1449d98cc43fc7561a --- main/asterisk.c | 5 + main/pbx.c | 1526 +-------------------------------------------------- main/pbx_builtins.c | 1500 ++++++++++++++++++++++++++++++++++++++++++++++++++ main/pbx_private.h | 37 ++ 4 files changed, 1571 insertions(+), 1497 deletions(-) create mode 100644 main/pbx_builtins.c create mode 100644 main/pbx_private.h (limited to 'main') diff --git a/main/asterisk.c b/main/asterisk.c index 3f16caf06..18b5ddf87 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -4643,6 +4643,11 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou exit(1); } + if (load_pbx_builtins()) { + printf("Failed: load_pbx_builtins\n%s", term_quit()); + exit(1); + } + if (ast_local_init()) { printf("Failed: ast_local_init\n%s", term_quit()); exit(1); diff --git a/main/pbx.c b/main/pbx.c index be003286d..0ed043cd4 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -73,6 +73,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/stasis_channels.h" #include "asterisk/dial.h" #include "asterisk/vector.h" +#include "pbx_private.h" /*! * \note I M P O R T A N T : @@ -96,637 +97,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */ /*** DOCUMENTATION - - - Answer a channel if ringing. - - - - Asterisk will wait this number of milliseconds before returning to - the dialplan after answering the call. - - - - If the call has not been answered, this application will - answer it. Otherwise, it has no effect on the call. - - - Hangup - - - - - Play an audio file while waiting for digits of an extension to go to. - - - - - - - - - - - - - - - Explicitly specifies which language to attempt to use for the requested sound files. - - - This is the dialplan context that this application will use when exiting - to a dialed extension. - - - - This application will play the given list of files (do not put extension) - while waiting for an extension to be dialed by the calling channel. To continue waiting - for digits after this application has finished playing files, the WaitExten - application should be used. - If one of the requested sound files does not exist, call processing will be terminated. - This application sets the following channel variable upon completion: - - - The status of the background attempt as a text string. - - - - - - - ControlPlayback - WaitExten - BackgroundDetect - TIMEOUT - - - - - Indicate the Busy condition. - - - - If specified, the calling channel will be hung up after the specified number of seconds. - Otherwise, this application will wait until the calling channel hangs up. - - - - This application will indicate the busy condition to the calling channel. - - - Congestion - Progress - Playtones - Hangup - - - - - Indicate the Congestion condition. - - - - If specified, the calling channel will be hung up after the specified number of seconds. - Otherwise, this application will wait until the calling channel hangs up. - - - - This application will indicate the congestion condition to the calling channel. - - - Busy - Progress - Playtones - Hangup - - - - - Conditional application execution based on the current time. - - - - - - - - - - - - - - - This application will execute the specified dialplan application, with optional - arguments, if the current time matches the given time specification. - - - Exec - ExecIf - TryExec - GotoIfTime - - - - - Jump to a particular priority, extension, or context. - - - - - - - - This application will set the current context, extension, and priority in the channel structure. - After it completes, the pbx engine will continue dialplan execution at the specified location. - If no specific extension, or extension and - context, are specified, then this application will - just set the specified priority of the current extension. - At least a priority is required as an argument, or the goto will - return a -1, and the channel and call will be terminated. - If the location that is put into the channel information is bogus, and asterisk cannot - find that location in the dialplan, then the execution engine will try to find and execute the code in - the i (invalid) extension in the current context. If that does not exist, it will try to execute the - h extension. If neither the h nor i extensions - have been defined, the channel is hung up, and the execution of instructions on the channel is terminated. - What this means is that, for example, you specify a context that does not exist, then - it will not be possible to find the h or i extensions, - and the call will terminate! - - - GotoIf - GotoIfTime - Gosub - Macro - - - - - Conditional goto. - - - - - - Continue at labeliftrue if the condition is true. - Takes the form similar to Goto() of [[context,]extension,]priority. - - - Continue at labeliffalse if the condition is false. - Takes the form similar to Goto() of [[context,]extension,]priority. - - - - - This application will set the current context, extension, and priority in the channel structure - based on the evaluation of the given condition. After this application completes, the - pbx engine will continue dialplan execution at the specified location in the dialplan. - The labels are specified with the same syntax as used within the Goto application. - If the label chosen by the condition is omitted, no jump is performed, and the execution passes to the - next instruction. If the target location is bogus, and does not exist, the execution engine will try - to find and execute the code in the i (invalid) extension in the current context. - If that does not exist, it will try to execute the h extension. - If neither the h nor i extensions have been defined, - the channel is hung up, and the execution of instructions on the channel is terminated. - Remember that this command can set the current context, and if the context specified - does not exist, then it will not be able to find any 'h' or 'i' extensions there, and - the channel and call will both be terminated!. - - - Goto - GotoIfTime - GosubIf - MacroIf - - - - - Conditional Goto based on the current time. - - - - - - - - - - - - Continue at labeliftrue if the condition is true. - Takes the form similar to Goto() of [[context,]extension,]priority. - - - Continue at labeliffalse if the condition is false. - Takes the form similar to Goto() of [[context,]extension,]priority. - - - - - This application will set the context, extension, and priority in the channel structure - based on the evaluation of the given time specification. After this application completes, - the pbx engine will continue dialplan execution at the specified location in the dialplan. - If the current time is within the given time specification, the channel will continue at - labeliftrue. Otherwise the channel will continue at labeliffalse. - If the label chosen by the condition is omitted, no jump is performed, and execution passes to the next - instruction. If the target jump location is bogus, the same actions would be taken as for Goto. - Further information on the time specification can be found in examples - illustrating how to do time-based context includes in the dialplan. - - - GotoIf - Goto - IFTIME - TESTTIME - - - - - Import a variable from a channel into a new variable. - - - - - - - - - - This application imports a variable from the specified - channel (as opposed to the current one) and stores it as a variable - (newvar) in the current channel (the channel that is calling this - application). Variables created by this application have the same inheritance properties as those - created with the Set application. - - - Set - - - - - Hang up the calling channel. - - - - If a causecode is given the channel's - hangup cause will be set to the given value. - - - - This application will hang up the calling channel. - - - Answer - Busy - Congestion - - - - - Returns AST_PBX_INCOMPLETE value. - - - - If specified, then Incomplete will not attempt to answer the channel first. - Most channel types need to be in Answer state in order to receive DTMF. - - - - Signals the PBX routines that the previous matched extension is incomplete - and that further input should be allowed before matching can be considered - to be complete. Can be used within a pattern match when certain criteria warrants - a longer match. - - - - - Do Nothing (No Operation). - - - - Any text provided can be viewed at the Asterisk CLI. - - - - This application does nothing. However, it is useful for debugging purposes. - This method can be used to see the evaluations of variables or functions without having any effect. - - - Verbose - Log - - - - - Indicate proceeding. - - - - This application will request that a proceeding message be provided to the calling channel. - - - - - Indicate progress. - - - - This application will request that in-band progress information be provided to the calling channel. - - - Busy - Congestion - Ringing - Playtones - - - - - Handle an exceptional condition. - - - - - - This application will jump to the e extension in the current context, setting the - dialplan function EXCEPTION(). If the e extension does not exist, the call will hangup. - - - Exception - - - - - Indicate ringing tone. - - - - This application will request that the channel indicate a ringing tone to the user. - - - Busy - Congestion - Progress - Playtones - - - - - Say Alpha. - - - - - - This application will play the sounds that correspond to the letters - of the given string. If the channel variable - SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), - then this application will react to DTMF in the same way as - Background. - - - SayDigits - SayNumber - SayPhonetic - CHANNEL - - - - - Say Alpha. - - - - - - Case sensitive (all) pronunciation. - (Ex: SayAlphaCase(a,aBc); - lowercase a uppercase b lowercase c). - - - Case sensitive (lower) pronunciation. - (Ex: SayAlphaCase(l,aBc); - lowercase a b lowercase c). - - - Case insensitive pronunciation. Equivalent to SayAlpha. - (Ex: SayAlphaCase(n,aBc) - a b c). - - - Case sensitive (upper) pronunciation. - (Ex: SayAlphaCase(u,aBc); - a uppercase b c). - - - - - - - This application will play the sounds that correspond to the letters of the - given string. Optionally, a casetype may be - specified. This will be used for case-insensitive or case-sensitive pronunciations. If the channel - variable SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this - application will react to DTMF in the same way as Background. - - - SayDigits - SayNumber - SayPhonetic - SayAlpha - CHANNEL - - - - - Say Digits. - - - - - - This application will play the sounds that correspond to the digits of - the given number. This will use the language that is currently set for the channel. - If the channel variable SAY_DTMF_INTERRUPT is set to 'true' - (case insensitive), then this application will react to DTMF in the same way as - Background. - - - SayAlpha - SayNumber - SayPhonetic - CHANNEL - - - - - Say Number. - - - - - - - This application will play the sounds that correspond to the given - digits. Optionally, a gender may be - specified. This will use the language that is currently set for the channel. See the CHANNEL() - function for more information on setting the language for the channel. If the channel variable - SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this - application will react to DTMF in the same way as Background. - - - SayAlpha - SayDigits - SayPhonetic - CHANNEL - - - - - Say Phonetic. - - - - - - This application will play the sounds from the phonetic alphabet that correspond to the - letters in the given string. If the channel variable - SAY_DTMF_INTERRUPT is set to 'true' (case insensitive), then this - application will react to DTMF in the same way as Background. - - - SayAlpha - SayDigits - SayNumber - - - - - Set channel variable or function value. - - - - - - - This function can be used to set the value of channel variables or dialplan functions. - When setting variables, if the variable name is prefixed with _, - the variable will be inherited into channels created from the current channel. - If the variable name is prefixed with __, the variable will be - inherited into channels created from the current channel and all children channels. - If (and only if), in /etc/asterisk/asterisk.conf, you have - a [compat] category, and you have app_set = 1.4 under that, then - the behavior of this app changes, and strips surrounding quotes from the right hand side as - it did previously in 1.4. - The advantages of not stripping out quoting, and not caring about the separator characters (comma and vertical bar) - were sufficient to make these changes in 1.6. Confusion about how many backslashes would be needed to properly - protect separators and quotes in various database access strings has been greatly - reduced by these changes. - - - MSet - GLOBAL - SET - ENV - - - - - Set channel variable(s) or function value(s). - - - - - - - - - - - - - This function can be used to set the value of channel variables or dialplan functions. - When setting variables, if the variable name is prefixed with _, - the variable will be inherited into channels created from the current channel - If the variable name is prefixed with __, the variable will be - inherited into channels created from the current channel and all children channels. - MSet behaves in a similar fashion to the way Set worked in 1.2/1.4 and is thus - prone to doing things that you may not expect. For example, it strips surrounding - double-quotes from the right-hand side (value). If you need to put a separator - character (comma or vert-bar), you will need to escape them by inserting a backslash - before them. Avoid its use if possible. - - - Set - - - - - Set the AMA Flags. - - - - - - This application will set the channel's AMA Flags for billing purposes. - This application is deprecated. Please use the CHANNEL function instead. - - - CDR - CHANNEL - - - - - Waits for some time. - - - - Can be passed with fractions of a second. For example, 1.5 will ask the - application to wait for 1.5 seconds. - - - - This application waits for a specified number of seconds. - - - - - Waits for an extension to be entered. - - - - Can be passed with fractions of a second. For example, 1.5 will ask the - application to wait for 1.5 seconds. - - - - - - - - - This application waits for the user to enter a new extension for a specified number - of seconds. - - - - Background - TIMEOUT - - Retrieve the details of the current dialplan exception. @@ -850,32 +220,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define SWITCH_DATA_LENGTH 256 -#define VAR_BUF_SIZE 4096 - #define VAR_NORMAL 1 #define VAR_SOFTTRAN 2 #define VAR_HARDTRAN 3 -#define BACKGROUND_SKIP (1 << 0) -#define BACKGROUND_NOANSWER (1 << 1) -#define BACKGROUND_MATCHEXTEN (1 << 2) -#define BACKGROUND_PLAYBACK (1 << 3) - -AST_APP_OPTIONS(background_opts, { - AST_APP_OPTION('s', BACKGROUND_SKIP), - AST_APP_OPTION('n', BACKGROUND_NOANSWER), - AST_APP_OPTION('m', BACKGROUND_MATCHEXTEN), - AST_APP_OPTION('p', BACKGROUND_PLAYBACK), -}); - -#define WAITEXTEN_MOH (1 << 0) -#define WAITEXTEN_DIALTONE (1 << 1) - -AST_APP_OPTIONS(waitexten_opts, { - AST_APP_OPTION_ARG('m', WAITEXTEN_MOH, 0), - AST_APP_OPTION_ARG('d', WAITEXTEN_DIALTONE, 0), -}); - struct ast_context; struct ast_app; @@ -1263,34 +611,10 @@ struct pbx_exception { int priority; /*!< Priority associated with this exception */ }; -static int pbx_builtin_answer(struct ast_channel *, const char *); -static int pbx_builtin_goto(struct ast_channel *, const char *); -static int pbx_builtin_hangup(struct ast_channel *, const char *); -static int pbx_builtin_background(struct ast_channel *, const char *); -static int pbx_builtin_wait(struct ast_channel *, const char *); -static int pbx_builtin_waitexten(struct ast_channel *, const char *); -static int pbx_builtin_incomplete(struct ast_channel *, const char *); -static int pbx_builtin_setamaflags(struct ast_channel *, const char *); -static int pbx_builtin_ringing(struct ast_channel *, const char *); -static int pbx_builtin_proceeding(struct ast_channel *, const char *); -static int pbx_builtin_progress(struct ast_channel *, const char *); -static int pbx_builtin_congestion(struct ast_channel *, const char *); -static int pbx_builtin_busy(struct ast_channel *, const char *); -static int pbx_builtin_noop(struct ast_channel *, const char *); -static int pbx_builtin_gotoif(struct ast_channel *, const char *); -static int pbx_builtin_gotoiftime(struct ast_channel *, const char *); -static int pbx_builtin_execiftime(struct ast_channel *, const char *); -static int pbx_builtin_saynumber(struct ast_channel *, const char *); -static int pbx_builtin_saydigits(struct ast_channel *, const char *); -static int pbx_builtin_saycharacters(struct ast_channel *, const char *); -static int pbx_builtin_saycharacters_case(struct ast_channel *, const char *); -static int pbx_builtin_sayphonetic(struct ast_channel *, const char *); static int matchcid(const char *cidpattern, const char *callerid); #ifdef NEED_DEBUG static void log_match_char_tree(struct match_char *node, char *prefix); /* for use anywhere */ #endif -static int pbx_builtin_importvar(struct ast_channel *, const char *); -static void set_ext_pri(struct ast_channel *c, const char *exten, int pri); static void new_find_extension(const char *str, struct scoreboard *score, struct match_char *tree, int length, int spec, const char *callerid, const char *label, enum ext_match_t action); @@ -1442,43 +766,6 @@ static int totalcalls; */ static AST_RWLIST_HEAD_STATIC(acf_root, ast_custom_function); -/*! \brief Declaration of builtin applications */ -static struct pbx_builtin { - char name[AST_MAX_APP]; - int (*execute)(struct ast_channel *chan, const char *data); -} builtins[] = -{ - /* These applications are built into the PBX core and do not - need separate modules */ - - { "Answer", pbx_builtin_answer }, - { "BackGround", pbx_builtin_background }, - { "Busy", pbx_builtin_busy }, - { "Congestion", pbx_builtin_congestion }, - { "ExecIfTime", pbx_builtin_execiftime }, - { "Goto", pbx_builtin_goto }, - { "GotoIf", pbx_builtin_gotoif }, - { "GotoIfTime", pbx_builtin_gotoiftime }, - { "ImportVar", pbx_builtin_importvar }, - { "Hangup", pbx_builtin_hangup }, - { "Incomplete", pbx_builtin_incomplete }, - { "NoOp", pbx_builtin_noop }, - { "Proceeding", pbx_builtin_proceeding }, - { "Progress", pbx_builtin_progress }, - { "RaiseException", pbx_builtin_raise_exception }, - { "Ringing", pbx_builtin_ringing }, - { "SayAlpha", pbx_builtin_saycharacters }, - { "SayAlphaCase", pbx_builtin_saycharacters_case }, - { "SayDigits", pbx_builtin_saydigits }, - { "SayNumber", pbx_builtin_saynumber }, - { "SayPhonetic", pbx_builtin_sayphonetic }, - { "Set", pbx_builtin_setvar }, - { "MSet", pbx_builtin_setvar_multiple }, - { "SetAMAFlags", pbx_builtin_setamaflags }, - { "Wait", pbx_builtin_wait }, - { "WaitExten", pbx_builtin_waitexten } -}; - static struct ast_context *contexts; static struct ast_hashtab *contexts_table = NULL; @@ -3822,7 +3109,7 @@ static const struct ast_datastore_info exception_store_info = { * \retval 0 on success. * \retval -1 on error. */ -static int raise_exception(struct ast_channel *chan, const char *reason, int priority) +int raise_exception(struct ast_channel *chan, const char *reason, int priority) { struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL); struct pbx_exception *exception = NULL; @@ -3848,12 +3135,6 @@ static int raise_exception(struct ast_channel *chan, const char *reason, int pri return 0; } -int pbx_builtin_raise_exception(struct ast_channel *chan, const char *reason) -{ - /* Priority will become 1, next time through the AUTOLOOP */ - return raise_exception(chan, reason, 0); -} - static int acf_exception_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen) { struct ast_datastore *ds = ast_channel_datastore_find(chan, &exception_store_info, NULL); @@ -6463,7 +5744,7 @@ static char *handle_show_hangup_all(struct ast_cli_entry *e, int cmd, struct ast } /*! helper function to set extension and priority */ -static void set_ext_pri(struct ast_channel *c, const char *exten, int pri) +void set_ext_pri(struct ast_channel *c, const char *exten, int pri) { ast_channel_lock(c); ast_channel_exten_set(c, exten); @@ -6726,11 +6007,11 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, status = "UNKNOWN"; ast_verb(3, "Auto fallthrough, channel '%s' status is '%s'\n", ast_channel_name(c), status); if (!strcasecmp(status, "CONGESTION")) - res = pbx_builtin_congestion(c, "10"); + res = indicate_congestion(c, "10"); else if (!strcasecmp(status, "CHANUNAVAIL")) - res = pbx_builtin_congestion(c, "10"); + res = indicate_congestion(c, "10"); else if (!strcasecmp(status, "BUSY")) - res = pbx_builtin_busy(c, "10"); + res = indicate_busy(c, "10"); error = 1; /* XXX disable message */ break; /* exit from the 'for' loop */ } @@ -11050,7 +10331,7 @@ void ast_context_destroy(struct ast_context *con, const char *registrar) ast_unlock_contexts(); } -static void wait_for_hangup(struct ast_channel *chan, const void *data) +void wait_for_hangup(struct ast_channel *chan, const void *data) { int res; struct ast_frame *f; @@ -11073,211 +10354,29 @@ static void wait_for_hangup(struct ast_channel *chan, const void *data) } /*! - * \ingroup applications + * \ingroup functions */ -static int pbx_builtin_proceeding(struct ast_channel *chan, const char *data) +static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value) { - ast_indicate(chan, AST_CONTROL_PROCEEDING); - return 0; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_progress(struct ast_channel *chan, const char *data) -{ - ast_indicate(chan, AST_CONTROL_PROGRESS); - return 0; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_ringing(struct ast_channel *chan, const char *data) -{ - ast_indicate(chan, AST_CONTROL_RINGING); - return 0; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_busy(struct ast_channel *chan, const char *data) -{ - ast_indicate(chan, AST_CONTROL_BUSY); - /* Don't change state of an UP channel, just indicate - busy in audio */ - ast_channel_lock(chan); - if (ast_channel_state(chan) != AST_STATE_UP) { - ast_channel_hangupcause_set(chan, AST_CAUSE_BUSY); - ast_setstate(chan, AST_STATE_BUSY); - } - ast_channel_unlock(chan); - wait_for_hangup(chan, data); - return -1; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_congestion(struct ast_channel *chan, const char *data) -{ - ast_indicate(chan, AST_CONTROL_CONGESTION); - /* Don't change state of an UP channel, just indicate - congestion in audio */ - ast_channel_lock(chan); - if (ast_channel_state(chan) != AST_STATE_UP) { - ast_channel_hangupcause_set(chan, AST_CAUSE_CONGESTION); - ast_setstate(chan, AST_STATE_BUSY); - } - ast_channel_unlock(chan); - wait_for_hangup(chan, data); - return -1; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_answer(struct ast_channel *chan, const char *data) -{ - int delay = 0; - char *parse; - AST_DECLARE_APP_ARGS(args, - AST_APP_ARG(delay); - AST_APP_ARG(answer_cdr); - ); - - if (ast_strlen_zero(data)) { - return __ast_answer(chan, 0); - } - - parse = ast_strdupa(data); - - AST_STANDARD_APP_ARGS(args, parse); - - if (!ast_strlen_zero(args.delay) && (ast_channel_state(chan) != AST_STATE_UP)) - delay = atoi(data); - - if (delay < 0) { - delay = 0; - } - - if (!ast_strlen_zero(args.answer_cdr) && !strcasecmp(args.answer_cdr, "nocdr")) { - ast_log(AST_LOG_WARNING, "The nocdr option for the Answer application has been removed and is no longer supported.\n"); - } - - return __ast_answer(chan, delay); -} - -static int pbx_builtin_incomplete(struct ast_channel *chan, const char *data) -{ - const char *options = data; - int answer = 1; - - /* Some channels can receive DTMF in unanswered state; some cannot */ - if (!ast_strlen_zero(options) && strchr(options, 'n')) { - answer = 0; - } - - /* If the channel is hungup, stop waiting */ - if (ast_check_hangup(chan)) { - return -1; - } else if (ast_channel_state(chan) != AST_STATE_UP && answer) { - __ast_answer(chan, 0); - } - - ast_indicate(chan, AST_CONTROL_INCOMPLETE); - - return AST_PBX_INCOMPLETE; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_setamaflags(struct ast_channel *chan, const char *data) -{ - ast_log(AST_LOG_WARNING, "The SetAMAFlags application is deprecated. Please use the CHANNEL function instead.\n"); - - if (ast_strlen_zero(data)) { - ast_log(AST_LOG_WARNING, "No parameter passed to SetAMAFlags\n"); - return 0; - } - /* Copy the AMA Flags as specified */ - ast_channel_lock(chan); - if (isdigit(data[0])) { - int amaflags; - if (sscanf(data, "%30d", &amaflags) != 1) { - ast_log(AST_LOG_WARNING, "Unable to set AMA flags on channel %s\n", ast_channel_name(chan)); - ast_channel_unlock(chan); - return 0; - } - ast_channel_amaflags_set(chan, amaflags); - } else { - ast_channel_amaflags_set(chan, ast_channel_string2amaflag(data)); - } - ast_channel_unlock(chan); - return 0; -} - -/*! - * \ingroup applications - */ -static int pbx_builtin_hangup(struct ast_channel *chan, const char *data) -{ - int cause; - - ast_set_hangupsource(chan, "dialplan/builtin", 0); - - if (!ast_strlen_zero(data)) { - cause = ast_str2cause(data); - if (cause <= 0) { - if (sscanf(data, "%30d", &cause) != 1 || cause <= 0) { - ast_log(LOG_WARNING, "Invalid cause given to Hangup(): \"%s\"\n", data); - cause = 0; - } - } - } else { - cause = 0; - } - - ast_channel_lock(chan); - if (cause <= 0) { - cause = ast_channel_hangupcause(chan); - if (cause <= 0) { - cause = AST_CAUSE_NORMAL_CLEARING; - } - } - ast_channel_hangupcause_set(chan, cause); - ast_softhangup_nolock(chan, AST_SOFTHANGUP_EXPLICIT); - ast_channel_unlock(chan); - - return -1; -} - -/*! - * \ingroup functions - */ -static int testtime_write(struct ast_channel *chan, const char *cmd, char *var, const char *value) -{ - struct ast_tm tm; - struct timeval tv; - char *remainder, result[30], timezone[80]; - - /* Turn off testing? */ - if (!pbx_checkcondition(value)) { - pbx_builtin_setvar_helper(chan, "TESTTIME", NULL); - return 0; - } - - /* Parse specified time */ - if (!(remainder = ast_strptime(value, "%Y/%m/%d %H:%M:%S", &tm))) { - return -1; - } - sscanf(remainder, "%79s", timezone); - tv = ast_mktime(&tm, S_OR(timezone, NULL)); - - snprintf(result, sizeof(result), "%ld", (long) tv.tv_sec); - pbx_builtin_setvar_helper(chan, "__TESTTIME", result); + struct ast_tm tm; + struct timeval tv; + char *remainder, result[30], timezone[80]; + + /* Turn off testing? */ + if (!pbx_checkcondition(value)) { + pbx_builtin_setvar_helper(chan, "TESTTIME", NULL); + return 0; + } + + /* Parse specified time */ + if (!(remainder = ast_strptime(value, "%Y/%m/%d %H:%M:%S", &tm))) { + return -1; + } + sscanf(remainder, "%79s", timezone); + tv = ast_mktime(&tm, S_OR(timezone, NULL)); + + snprintf(result, sizeof(result), "%ld", (long) tv.tv_sec); + pbx_builtin_setvar_helper(chan, "__TESTTIME", result); return 0; } @@ -11286,333 +10385,6 @@ static struct ast_custom_function testtime_function = { .write = testtime_write, }; -/*! - * \ingroup applications - */ -static int pbx_builtin_gotoiftime(struct ast_channel *chan, const char *data) -{ - char *s, *ts, *branch1, *branch2, *branch; - struct ast_timing timing; - const char *ctime; - struct timeval tv = ast_tvnow(); - long timesecs; - - if (!chan) { - ast_log(LOG_WARNING, "GotoIfTime requires a channel on which to operate\n"); - return -1; - } - - if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "GotoIfTime requires an argument:\n