#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 | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "While Loops and Conditional Execution" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static char * | continue_app = "ContinueWhile" |
static char * | continue_desc |
static char * | continue_synopsis = "Restart a While loop" |
static char * | exit_app = "ExitWhile" |
static char * | exit_desc |
static char * | exit_synopsis = "End a While loop" |
static char * | start_app = "While" |
static char * | start_desc |
static char * | start_synopsis = "Start a while loop" |
static char * | stop_app = "EndWhile" |
static char * | stop_desc |
static char * | stop_synopsis = "End a while loop" |
Definition in file app_while.c.
#define VAR_SIZE 64 |
static void __reg_module | ( | void | ) | [static] |
Definition at line 311 of file app_while.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 311 of file app_while.c.
static int _while_exec | ( | struct ast_channel * | chan, | |
void * | data, | |||
int | end | |||
) | [static] |
Definition at line 146 of file app_while.c.
References ast_channel_lock, ast_channel_unlock, ast_log(), ast_parseable_goto(), ast_strdupa, ast_verb, ast_waitfordigit(), chan, ast_channel::context, ast_channel::exten, find_matching_endwhile(), get_index(), 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().
00147 { 00148 int res=0; 00149 const char *while_pri = NULL; 00150 char *my_name = NULL; 00151 const char *condition = NULL, *label = NULL; 00152 char varname[VAR_SIZE], end_varname[VAR_SIZE]; 00153 const char *prefix = "WHILE"; 00154 size_t size=0; 00155 int used_index_i = -1, x=0; 00156 char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; 00157 00158 if (!chan) { 00159 /* huh ? */ 00160 return -1; 00161 } 00162 00163 #if 0 00164 /* dont want run away loops if the chan isn't even up 00165 this is up for debate since it slows things down a tad ...... 00166 00167 Debate is over... this prevents While/EndWhile from working 00168 within the "h" extension. Not good. 00169 */ 00170 if (ast_waitfordigit(chan,1) < 0) 00171 return -1; 00172 #endif 00173 00174 for (x=0;;x++) { 00175 if (get_index(chan, prefix, x)) { 00176 used_index_i = x; 00177 } else 00178 break; 00179 } 00180 00181 snprintf(used_index, VAR_SIZE, "%d", used_index_i); 00182 snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); 00183 00184 if (!end) 00185 condition = ast_strdupa(data); 00186 00187 size = strlen(chan->context) + strlen(chan->exten) + 32; 00188 my_name = alloca(size); 00189 memset(my_name, 0, size); 00190 snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); 00191 00192 ast_channel_lock(chan); 00193 if (end) { 00194 label = used_index; 00195 } else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { 00196 label = new_index; 00197 pbx_builtin_setvar_helper(chan, my_name, label); 00198 } 00199 snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); 00200 if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { 00201 while_pri = ast_strdupa(while_pri); 00202 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00203 } 00204 ast_channel_unlock(chan); 00205 00206 00207 if ((!end && !pbx_checkcondition(condition)) || (end == 2)) { 00208 /* Condition Met (clean up helper vars) */ 00209 const char *goto_str; 00210 pbx_builtin_setvar_helper(chan, varname, NULL); 00211 pbx_builtin_setvar_helper(chan, my_name, NULL); 00212 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00213 ast_channel_lock(chan); 00214 if ((goto_str = pbx_builtin_getvar_helper(chan, end_varname))) { 00215 ast_parseable_goto(chan, goto_str); 00216 pbx_builtin_setvar_helper(chan, end_varname, NULL); 00217 } else { 00218 int pri = find_matching_endwhile(chan); 00219 if (pri > 0) { 00220 ast_verb(3, "Jumping to priority %d\n", pri); 00221 chan->priority = pri; 00222 } else { 00223 ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); 00224 } 00225 } 00226 ast_channel_unlock(chan); 00227 return res; 00228 } 00229 00230 if (!end && !while_pri) { 00231 char *goto_str; 00232 size = strlen(chan->context) + strlen(chan->exten) + 32; 00233 goto_str = alloca(size); 00234 memset(goto_str, 0, size); 00235 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); 00236 pbx_builtin_setvar_helper(chan, varname, goto_str); 00237 } 00238 00239 else if (end && while_pri) { 00240 /* END of loop */ 00241 snprintf(end_varname, VAR_SIZE, "END_%s", varname); 00242 if (! pbx_builtin_getvar_helper(chan, end_varname)) { 00243 char *goto_str; 00244 size = strlen(chan->context) + strlen(chan->exten) + 32; 00245 goto_str = alloca(size); 00246 memset(goto_str, 0, size); 00247 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); 00248 pbx_builtin_setvar_helper(chan, end_varname, goto_str); 00249 } 00250 ast_parseable_goto(chan, while_pri); 00251 } 00252 00253 return res; 00254 }
static int find_matching_endwhile | ( | struct ast_channel * | chan | ) | [static] |
Definition at line 105 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(), chan, 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().
00106 { 00107 struct ast_context *c; 00108 int res=-1; 00109 00110 if (ast_rdlock_contexts()) { 00111 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00112 return -1; 00113 } 00114 00115 for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) { 00116 struct ast_exten *e; 00117 00118 if (!ast_rdlock_context(c)) { 00119 if (!strcmp(ast_get_context_name(c), chan->context)) { 00120 /* This is the matching context we want */ 00121 int cur_priority = chan->priority + 1, level=1; 00122 00123 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)) { 00124 if (!strcasecmp(ast_get_extension_app(e), "WHILE")) { 00125 level++; 00126 } else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) { 00127 level--; 00128 } 00129 00130 if (level == 0) { 00131 res = cur_priority; 00132 break; 00133 } 00134 } 00135 } 00136 ast_unlock_context(c); 00137 if (res > 0) { 00138 break; 00139 } 00140 } 00141 } 00142 ast_unlock_contexts(); 00143 return res; 00144 }
static struct ast_exten* find_matching_priority | ( | struct ast_context * | c, | |
const char * | exten, | |||
int | priority, | |||
const char * | callerid | |||
) | [static] |
Definition at line 70 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(), ast_walk_extension_priorities(), and find_matching_priority().
00071 { 00072 struct ast_exten *e; 00073 struct ast_include *i; 00074 struct ast_context *c2; 00075 00076 for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { 00077 if (ast_extension_match(ast_get_extension_name(e), exten)) { 00078 int needmatch = ast_get_extension_matchcid(e); 00079 if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || 00080 (!needmatch)) { 00081 /* This is the matching extension we want */ 00082 struct ast_exten *p; 00083 for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { 00084 if (priority != ast_get_extension_priority(p)) 00085 continue; 00086 return p; 00087 } 00088 } 00089 } 00090 } 00091 00092 /* No match; run through includes */ 00093 for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { 00094 for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { 00095 if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { 00096 e = find_matching_priority(c2, exten, priority, callerid); 00097 if (e) 00098 return e; 00099 } 00100 } 00101 } 00102 return NULL; 00103 }
static const char* get_index | ( | struct ast_channel * | chan, | |
const char * | prefix, | |||
int | idx | |||
) | [static] |
Definition at line 63 of file app_while.c.
References chan, pbx_builtin_getvar_helper(), and VAR_SIZE.
00063 { 00064 char varname[VAR_SIZE]; 00065 00066 snprintf(varname, VAR_SIZE, "%s_%d", prefix, idx); 00067 return pbx_builtin_getvar_helper(chan, varname); 00068 }
static int load_module | ( | void | ) | [static] |
Definition at line 299 of file app_while.c.
References ast_register_application, while_continue_exec(), while_end_exec(), while_exit_exec(), and while_start_exec().
00300 { 00301 int res; 00302 00303 res = ast_register_application(start_app, while_start_exec, start_synopsis, start_desc); 00304 res |= ast_register_application(stop_app, while_end_exec, stop_synopsis, stop_desc); 00305 res |= ast_register_application(exit_app, while_exit_exec, exit_synopsis, exit_desc); 00306 res |= ast_register_application(continue_app, while_continue_exec, continue_synopsis, continue_desc); 00307 00308 return res; 00309 }
static int unload_module | ( | void | ) | [static] |
Definition at line 287 of file app_while.c.
References ast_unregister_application().
00288 { 00289 int res; 00290 00291 res = ast_unregister_application(start_app); 00292 res |= ast_unregister_application(stop_app); 00293 res |= ast_unregister_application(exit_app); 00294 res |= ast_unregister_application(continue_app); 00295 00296 return res; 00297 }
static int while_continue_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 268 of file app_while.c.
References ast_parseable_goto(), chan, get_index(), and prefix.
Referenced by load_module().
00269 { 00270 int x; 00271 const char *prefix = "WHILE", *while_pri=NULL; 00272 00273 for (x = 0; ; x++) { 00274 const char *tmp = get_index(chan, prefix, x); 00275 if (tmp) 00276 while_pri = tmp; 00277 else 00278 break; 00279 } 00280 00281 if (while_pri) 00282 ast_parseable_goto(chan, while_pri); 00283 00284 return 0; 00285 }
static int while_end_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 260 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00260 { 00261 return _while_exec(chan, data, 1); 00262 }
static int while_exit_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 264 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00264 { 00265 return _while_exec(chan, data, 2); 00266 }
static int while_start_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 256 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00256 { 00257 return _while_exec(chan, data, 0); 00258 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "While Loops and Conditional Execution" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 311 of file app_while.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 311 of file app_while.c.
char* continue_app = "ContinueWhile" [static] |
Definition at line 55 of file app_while.c.
char* continue_desc [static] |
Initial value:
" ContinueWhile(): Returns to the top of the while loop and re-evaluates the conditional.\n"
Definition at line 56 of file app_while.c.
char* continue_synopsis = "Restart a While loop" [static] |
Definition at line 58 of file app_while.c.
char* exit_app = "ExitWhile" [static] |
Definition at line 50 of file app_while.c.
char* exit_desc [static] |
Initial value:
" ExitWhile(): Exits a While() loop, whether or not the conditional has been satisfied.\n"
Definition at line 51 of file app_while.c.
char* exit_synopsis = "End a While loop" [static] |
Definition at line 53 of file app_while.c.
char* start_app = "While" [static] |
Definition at line 36 of file app_while.c.
char* start_desc [static] |
Initial value:
" While(<expr>): Start a While Loop. Execution will return to this\n" "point when EndWhile() is called until expr is no longer true.\n"
Definition at line 37 of file app_while.c.
char* start_synopsis = "Start a while loop" [static] |
Definition at line 41 of file app_while.c.
char* stop_app = "EndWhile" [static] |
Definition at line 44 of file app_while.c.
char* stop_desc [static] |
Initial value:
" EndWhile(): Return to the previous called While()\n"
Definition at line 45 of file app_while.c.
char* stop_synopsis = "End a while loop" [static] |
Definition at line 48 of file app_while.c.