#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 index) |
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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } |
static const 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 312 of file app_while.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 312 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_log(), ast_parseable_goto(), ast_strdupa, ast_strlen_zero(), 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 if (ast_strlen_zero(label)) { 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 00200 } 00201 00202 snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); 00203 while_pri = pbx_builtin_getvar_helper(chan, varname); 00204 00205 if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { 00206 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00207 } 00208 00209 00210 if ((!end && !pbx_checkcondition(condition)) || (end == 2)) { 00211 /* Condition Met (clean up helper vars) */ 00212 const char *goto_str; 00213 pbx_builtin_setvar_helper(chan, varname, NULL); 00214 pbx_builtin_setvar_helper(chan, my_name, NULL); 00215 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00216 if ((goto_str=pbx_builtin_getvar_helper(chan, end_varname))) { 00217 ast_parseable_goto(chan, goto_str); 00218 pbx_builtin_setvar_helper(chan, end_varname, NULL); 00219 } else { 00220 int pri = find_matching_endwhile(chan); 00221 if (pri > 0) { 00222 ast_verb(3, "Jumping to priority %d\n", pri); 00223 chan->priority = pri; 00224 } else { 00225 ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); 00226 } 00227 } 00228 return res; 00229 } 00230 00231 if (!end && !while_pri) { 00232 char *goto_str; 00233 size = strlen(chan->context) + strlen(chan->exten) + 32; 00234 goto_str = alloca(size); 00235 memset(goto_str, 0, size); 00236 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); 00237 pbx_builtin_setvar_helper(chan, varname, goto_str); 00238 } 00239 00240 else if (end && while_pri) { 00241 /* END of loop */ 00242 snprintf(end_varname, VAR_SIZE, "END_%s", varname); 00243 if (! pbx_builtin_getvar_helper(chan, end_varname)) { 00244 char *goto_str; 00245 size = strlen(chan->context) + strlen(chan->exten) + 32; 00246 goto_str = alloca(size); 00247 memset(goto_str, 0, size); 00248 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); 00249 pbx_builtin_setvar_helper(chan, end_varname, goto_str); 00250 } 00251 ast_parseable_goto(chan, while_pri); 00252 } 00253 00254 return res; 00255 }
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 | index | |||
) | [static] |
Definition at line 63 of file app_while.c.
References chan, pbx_builtin_getvar_helper(), and VAR_SIZE.
Referenced by _while_exec(), and while_continue_exec().
00063 { 00064 char varname[VAR_SIZE]; 00065 00066 snprintf(varname, VAR_SIZE, "%s_%d", prefix, index); 00067 return pbx_builtin_getvar_helper(chan, varname); 00068 }
static int load_module | ( | void | ) | [static] |
Definition at line 300 of file app_while.c.
References ast_register_application, while_continue_exec(), while_end_exec(), while_exit_exec(), and while_start_exec().
00301 { 00302 int res; 00303 00304 res = ast_register_application(start_app, while_start_exec, start_synopsis, start_desc); 00305 res |= ast_register_application(stop_app, while_end_exec, stop_synopsis, stop_desc); 00306 res |= ast_register_application(exit_app, while_exit_exec, exit_synopsis, exit_desc); 00307 res |= ast_register_application(continue_app, while_continue_exec, continue_synopsis, continue_desc); 00308 00309 return res; 00310 }
static int unload_module | ( | void | ) | [static] |
Definition at line 288 of file app_while.c.
References ast_unregister_application().
00289 { 00290 int res; 00291 00292 res = ast_unregister_application(start_app); 00293 res |= ast_unregister_application(stop_app); 00294 res |= ast_unregister_application(exit_app); 00295 res |= ast_unregister_application(continue_app); 00296 00297 return res; 00298 }
static int while_continue_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 269 of file app_while.c.
References ast_parseable_goto(), chan, get_index(), and prefix.
Referenced by load_module().
00270 { 00271 int x; 00272 const char *prefix = "WHILE", *while_pri=NULL; 00273 00274 for (x = 0; ; x++) { 00275 const char *tmp = get_index(chan, prefix, x); 00276 if (tmp) 00277 while_pri = tmp; 00278 else 00279 break; 00280 } 00281 00282 if (while_pri) 00283 ast_parseable_goto(chan, while_pri); 00284 00285 return 0; 00286 }
static int while_end_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 261 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00261 { 00262 return _while_exec(chan, data, 1); 00263 }
static int while_exit_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 265 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00265 { 00266 return _while_exec(chan, data, 2); 00267 }
static int while_start_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 257 of file app_while.c.
References _while_exec(), and chan.
Referenced by load_module().
00257 { 00258 return _while_exec(chan, data, 0); 00259 }
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 = "068e67f60f50dd9ee86464c05884a49d" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 312 of file app_while.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 312 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.