While Loop Implementation. More...
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/channel.h"
Go to the source code of this file.
Defines | |
#define | VAR_SIZE 64 |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | _while_exec (struct ast_channel *chan, void *data, int end) |
static int | find_matching_endwhile (struct ast_channel *chan) |
static struct ast_exten * | find_matching_priority (struct ast_context *c, const char *exten, int priority, const char *callerid) |
static const char * | get_index (struct ast_channel *chan, const char *prefix, int idx) |
static int | load_module (void) |
static int | unload_module (void) |
static int | while_continue_exec (struct ast_channel *chan, void *data) |
static int | while_end_exec (struct ast_channel *chan, void *data) |
static int | while_exit_exec (struct ast_channel *chan, void *data) |
static int | while_start_exec (struct ast_channel *chan, void *data) |
Variables | |
static struct ast_module_info __MODULE_INFO_SECTION | __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "While Loops and Conditional Execution" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | continue_app = "ContinueWhile" |
static char * | exit_app = "ExitWhile" |
static char * | start_app = "While" |
static char * | stop_app = "EndWhile" |
While Loop Implementation.
Definition in file app_while.c.
#define VAR_SIZE 64 |
Definition at line 103 of file app_while.c.
Referenced by _while_exec(), and get_index().
static void __reg_module | ( | void | ) | [static] |
Definition at line 354 of file app_while.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 354 of file app_while.c.
static int _while_exec | ( | struct ast_channel * | chan, |
void * | data, | ||
int | end | ||
) | [static] |
Definition at line 189 of file app_while.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_parseable_goto(), ast_strdupa, ast_verb, ast_waitfordigit(), ast_channel::context, ast_channel::exten, find_matching_endwhile(), get_index(), ast_exten::label, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), pbx_checkcondition(), prefix, ast_channel::priority, and VAR_SIZE.
Referenced by while_end_exec(), while_exit_exec(), and while_start_exec().
{ int res=0; const char *while_pri = NULL; char *my_name = NULL; const char *condition = NULL, *label = NULL; char varname[VAR_SIZE], end_varname[VAR_SIZE]; const char *prefix = "WHILE"; size_t size=0; int used_index_i = -1, x=0; char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; if (!chan) { /* huh ? */ return -1; } #if 0 /* dont want run away loops if the chan isn't even up this is up for debate since it slows things down a tad ...... Debate is over... this prevents While/EndWhile from working within the "h" extension. Not good. */ if (ast_waitfordigit(chan,1) < 0) return -1; #endif for (x=0;;x++) { if (get_index(chan, prefix, x)) { used_index_i = x; } else break; } snprintf(used_index, VAR_SIZE, "%d", used_index_i); snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); if (!end) condition = ast_strdupa(data); size = strlen(chan->context) + strlen(chan->exten) + 32; my_name = alloca(size); memset(my_name, 0, size); snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); ast_channel_lock(chan); if (end) { label = used_index; } else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { label = new_index; pbx_builtin_setvar_helper(chan, my_name, label); } snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { while_pri = ast_strdupa(while_pri); snprintf(end_varname,VAR_SIZE,"END_%s",varname); } ast_channel_unlock(chan); if ((!end && !pbx_checkcondition(condition)) || (end == 2)) { /* Condition Met (clean up helper vars) */ const char *goto_str; pbx_builtin_setvar_helper(chan, varname, NULL); pbx_builtin_setvar_helper(chan, my_name, NULL); snprintf(end_varname,VAR_SIZE,"END_%s",varname); ast_channel_lock(chan); if ((goto_str = pbx_builtin_getvar_helper(chan, end_varname))) { ast_parseable_goto(chan, goto_str); pbx_builtin_setvar_helper(chan, end_varname, NULL); } else { int pri = find_matching_endwhile(chan); if (pri > 0) { ast_verb(3, "Jumping to priority %d\n", pri); chan->priority = pri; } else { ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); } } ast_channel_unlock(chan); return res; } if (!end && !while_pri) { char *goto_str; size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); memset(goto_str, 0, size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); pbx_builtin_setvar_helper(chan, varname, goto_str); } else if (end && while_pri) { /* END of loop */ snprintf(end_varname, VAR_SIZE, "END_%s", varname); if (! pbx_builtin_getvar_helper(chan, end_varname)) { char *goto_str; size = strlen(chan->context) + strlen(chan->exten) + 32; goto_str = alloca(size); memset(goto_str, 0, size); snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); pbx_builtin_setvar_helper(chan, end_varname, goto_str); } ast_parseable_goto(chan, while_pri); } return res; }
static int find_matching_endwhile | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 148 of file app_while.c.
References ast_get_context_name(), ast_get_extension_app(), ast_log(), ast_rdlock_context(), ast_rdlock_contexts(), ast_unlock_context(), ast_unlock_contexts(), ast_walk_contexts(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, ast_channel::exten, find_matching_priority(), LOG_ERROR, and ast_channel::priority.
Referenced by _while_exec().
{ struct ast_context *c; int res=-1; if (ast_rdlock_contexts()) { ast_log(LOG_ERROR, "Failed to lock contexts list\n"); return -1; } for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) { struct ast_exten *e; if (!ast_rdlock_context(c)) { if (!strcmp(ast_get_context_name(c), chan->context)) { /* This is the matching context we want */ int cur_priority = chan->priority + 1, level=1; for (e = find_matching_priority(c, chan->exten, cur_priority, chan->cid.cid_num); e; e = find_matching_priority(c, chan->exten, ++cur_priority, chan->cid.cid_num)) { if (!strcasecmp(ast_get_extension_app(e), "WHILE")) { level++; } else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) { level--; } if (level == 0) { res = cur_priority; break; } } } ast_unlock_context(c); if (res > 0) { break; } } } ast_unlock_contexts(); return res; }
static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, |
const char * | exten, | ||
int | priority, | ||
const char * | callerid | ||
) | [static, read] |
Definition at line 113 of file app_while.c.
References ast_extension_match(), ast_get_context_name(), ast_get_extension_cidmatch(), ast_get_extension_matchcid(), ast_get_extension_name(), ast_get_extension_priority(), ast_get_include_name(), ast_walk_context_extensions(), ast_walk_context_includes(), ast_walk_contexts(), and ast_walk_extension_priorities().
Referenced by find_matching_endwhile().
{ struct ast_exten *e; struct ast_include *i; struct ast_context *c2; for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { if (ast_extension_match(ast_get_extension_name(e), exten)) { int needmatch = ast_get_extension_matchcid(e); if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || (!needmatch)) { /* This is the matching extension we want */ struct ast_exten *p; for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { if (priority != ast_get_extension_priority(p)) continue; return p; } } } } /* No match; run through includes */ for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { e = find_matching_priority(c2, exten, priority, callerid); if (e) return e; } } } return NULL; }
static const char* get_index | ( | struct ast_channel * | chan, |
const char * | prefix, | ||
int | idx | ||
) | [static] |
Definition at line 106 of file app_while.c.
References pbx_builtin_getvar_helper(), and VAR_SIZE.
Referenced by _while_exec(), and while_continue_exec().
{ char varname[VAR_SIZE]; snprintf(varname, VAR_SIZE, "%s_%d", prefix, idx); return pbx_builtin_getvar_helper(chan, varname); }
static int load_module | ( | void | ) | [static] |
Definition at line 342 of file app_while.c.
References ast_register_application_xml, while_continue_exec(), while_end_exec(), while_exit_exec(), and while_start_exec().
{ int res; res = ast_register_application_xml(start_app, while_start_exec); res |= ast_register_application_xml(stop_app, while_end_exec); res |= ast_register_application_xml(exit_app, while_exit_exec); res |= ast_register_application_xml(continue_app, while_continue_exec); return res; }
static int unload_module | ( | void | ) | [static] |
Definition at line 330 of file app_while.c.
References ast_unregister_application().
{ int res; res = ast_unregister_application(start_app); res |= ast_unregister_application(stop_app); res |= ast_unregister_application(exit_app); res |= ast_unregister_application(continue_app); return res; }
static int while_continue_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 311 of file app_while.c.
References ast_parseable_goto(), get_index(), and prefix.
Referenced by load_module().
{ int x; const char *prefix = "WHILE", *while_pri=NULL; for (x = 0; ; x++) { const char *tmp = get_index(chan, prefix, x); if (tmp) while_pri = tmp; else break; } if (while_pri) ast_parseable_goto(chan, while_pri); return 0; }
static int while_end_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 303 of file app_while.c.
References _while_exec().
Referenced by load_module().
{ return _while_exec(chan, data, 1); }
static int while_exit_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 307 of file app_while.c.
References _while_exec().
Referenced by load_module().
{ return _while_exec(chan, data, 2); }
static int while_start_exec | ( | struct ast_channel * | chan, |
void * | data | ||
) | [static] |
Definition at line 299 of file app_while.c.
References _while_exec().
Referenced by load_module().
{ return _while_exec(chan, data, 0); }
struct ast_module_info __MODULE_INFO_SECTION __mod_info = { __MODULE_INFO_GLOBALS .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "While Loops and Conditional Execution" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, } [static] |
Definition at line 354 of file app_while.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 354 of file app_while.c.
char* continue_app = "ContinueWhile" [static] |
Definition at line 101 of file app_while.c.
char* exit_app = "ExitWhile" [static] |
Definition at line 100 of file app_while.c.
char* start_app = "While" [static] |
Definition at line 98 of file app_while.c.
char* stop_app = "EndWhile" [static] |
Definition at line 99 of file app_while.c.