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 | __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 = "0901e4e500243c855563a2d78b0c03e4" , .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_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().
00190 { 00191 int res=0; 00192 const char *while_pri = NULL; 00193 char *my_name = NULL; 00194 const char *condition = NULL, *label = NULL; 00195 char varname[VAR_SIZE], end_varname[VAR_SIZE]; 00196 const char *prefix = "WHILE"; 00197 size_t size=0; 00198 int used_index_i = -1, x=0; 00199 char used_index[VAR_SIZE] = "0", new_index[VAR_SIZE] = "0"; 00200 00201 if (!chan) { 00202 /* huh ? */ 00203 return -1; 00204 } 00205 00206 #if 0 00207 /* dont want run away loops if the chan isn't even up 00208 this is up for debate since it slows things down a tad ...... 00209 00210 Debate is over... this prevents While/EndWhile from working 00211 within the "h" extension. Not good. 00212 */ 00213 if (ast_waitfordigit(chan,1) < 0) 00214 return -1; 00215 #endif 00216 00217 for (x=0;;x++) { 00218 if (get_index(chan, prefix, x)) { 00219 used_index_i = x; 00220 } else 00221 break; 00222 } 00223 00224 snprintf(used_index, VAR_SIZE, "%d", used_index_i); 00225 snprintf(new_index, VAR_SIZE, "%d", used_index_i + 1); 00226 00227 if (!end) 00228 condition = ast_strdupa(data); 00229 00230 size = strlen(chan->context) + strlen(chan->exten) + 32; 00231 my_name = alloca(size); 00232 memset(my_name, 0, size); 00233 snprintf(my_name, size, "%s_%s_%d", chan->context, chan->exten, chan->priority); 00234 00235 ast_channel_lock(chan); 00236 if (end) { 00237 label = used_index; 00238 } else if (!(label = pbx_builtin_getvar_helper(chan, my_name))) { 00239 label = new_index; 00240 pbx_builtin_setvar_helper(chan, my_name, label); 00241 } 00242 snprintf(varname, VAR_SIZE, "%s_%s", prefix, label); 00243 if ((while_pri = pbx_builtin_getvar_helper(chan, varname)) && !end) { 00244 while_pri = ast_strdupa(while_pri); 00245 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00246 } 00247 ast_channel_unlock(chan); 00248 00249 00250 if ((!end && !pbx_checkcondition(condition)) || (end == 2)) { 00251 /* Condition Met (clean up helper vars) */ 00252 const char *goto_str; 00253 pbx_builtin_setvar_helper(chan, varname, NULL); 00254 pbx_builtin_setvar_helper(chan, my_name, NULL); 00255 snprintf(end_varname,VAR_SIZE,"END_%s",varname); 00256 ast_channel_lock(chan); 00257 if ((goto_str = pbx_builtin_getvar_helper(chan, end_varname))) { 00258 ast_parseable_goto(chan, goto_str); 00259 pbx_builtin_setvar_helper(chan, end_varname, NULL); 00260 } else { 00261 int pri = find_matching_endwhile(chan); 00262 if (pri > 0) { 00263 ast_verb(3, "Jumping to priority %d\n", pri); 00264 chan->priority = pri; 00265 } else { 00266 ast_log(LOG_WARNING, "Couldn't find matching EndWhile? (While at %s@%s priority %d)\n", chan->context, chan->exten, chan->priority); 00267 } 00268 } 00269 ast_channel_unlock(chan); 00270 return res; 00271 } 00272 00273 if (!end && !while_pri) { 00274 char *goto_str; 00275 size = strlen(chan->context) + strlen(chan->exten) + 32; 00276 goto_str = alloca(size); 00277 memset(goto_str, 0, size); 00278 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority); 00279 pbx_builtin_setvar_helper(chan, varname, goto_str); 00280 } 00281 00282 else if (end && while_pri) { 00283 /* END of loop */ 00284 snprintf(end_varname, VAR_SIZE, "END_%s", varname); 00285 if (! pbx_builtin_getvar_helper(chan, end_varname)) { 00286 char *goto_str; 00287 size = strlen(chan->context) + strlen(chan->exten) + 32; 00288 goto_str = alloca(size); 00289 memset(goto_str, 0, size); 00290 snprintf(goto_str, size, "%s,%s,%d", chan->context, chan->exten, chan->priority+1); 00291 pbx_builtin_setvar_helper(chan, end_varname, goto_str); 00292 } 00293 ast_parseable_goto(chan, while_pri); 00294 } 00295 00296 return res; 00297 }
| 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().
00149 { 00150 struct ast_context *c; 00151 int res=-1; 00152 00153 if (ast_rdlock_contexts()) { 00154 ast_log(LOG_ERROR, "Failed to lock contexts list\n"); 00155 return -1; 00156 } 00157 00158 for (c=ast_walk_contexts(NULL); c; c=ast_walk_contexts(c)) { 00159 struct ast_exten *e; 00160 00161 if (!ast_rdlock_context(c)) { 00162 if (!strcmp(ast_get_context_name(c), chan->context)) { 00163 /* This is the matching context we want */ 00164 int cur_priority = chan->priority + 1, level=1; 00165 00166 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)) { 00167 if (!strcasecmp(ast_get_extension_app(e), "WHILE")) { 00168 level++; 00169 } else if (!strcasecmp(ast_get_extension_app(e), "ENDWHILE")) { 00170 level--; 00171 } 00172 00173 if (level == 0) { 00174 res = cur_priority; 00175 break; 00176 } 00177 } 00178 } 00179 ast_unlock_context(c); 00180 if (res > 0) { 00181 break; 00182 } 00183 } 00184 } 00185 ast_unlock_contexts(); 00186 return res; 00187 }
| 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().
00114 { 00115 struct ast_exten *e; 00116 struct ast_include *i; 00117 struct ast_context *c2; 00118 00119 for (e=ast_walk_context_extensions(c, NULL); e; e=ast_walk_context_extensions(c, e)) { 00120 if (ast_extension_match(ast_get_extension_name(e), exten)) { 00121 int needmatch = ast_get_extension_matchcid(e); 00122 if ((needmatch && ast_extension_match(ast_get_extension_cidmatch(e), callerid)) || 00123 (!needmatch)) { 00124 /* This is the matching extension we want */ 00125 struct ast_exten *p; 00126 for (p=ast_walk_extension_priorities(e, NULL); p; p=ast_walk_extension_priorities(e, p)) { 00127 if (priority != ast_get_extension_priority(p)) 00128 continue; 00129 return p; 00130 } 00131 } 00132 } 00133 } 00134 00135 /* No match; run through includes */ 00136 for (i=ast_walk_context_includes(c, NULL); i; i=ast_walk_context_includes(c, i)) { 00137 for (c2=ast_walk_contexts(NULL); c2; c2=ast_walk_contexts(c2)) { 00138 if (!strcmp(ast_get_context_name(c2), ast_get_include_name(i))) { 00139 e = find_matching_priority(c2, exten, priority, callerid); 00140 if (e) 00141 return e; 00142 } 00143 } 00144 } 00145 return NULL; 00146 }
| 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().
00106 { 00107 char varname[VAR_SIZE]; 00108 00109 snprintf(varname, VAR_SIZE, "%s_%d", prefix, idx); 00110 return pbx_builtin_getvar_helper(chan, varname); 00111 }
| 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().
00343 { 00344 int res; 00345 00346 res = ast_register_application_xml(start_app, while_start_exec); 00347 res |= ast_register_application_xml(stop_app, while_end_exec); 00348 res |= ast_register_application_xml(exit_app, while_exit_exec); 00349 res |= ast_register_application_xml(continue_app, while_continue_exec); 00350 00351 return res; 00352 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 330 of file app_while.c.
References ast_unregister_application().
00331 { 00332 int res; 00333 00334 res = ast_unregister_application(start_app); 00335 res |= ast_unregister_application(stop_app); 00336 res |= ast_unregister_application(exit_app); 00337 res |= ast_unregister_application(continue_app); 00338 00339 return res; 00340 }
| 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().
00312 { 00313 int x; 00314 const char *prefix = "WHILE", *while_pri=NULL; 00315 00316 for (x = 0; ; x++) { 00317 const char *tmp = get_index(chan, prefix, x); 00318 if (tmp) 00319 while_pri = tmp; 00320 else 00321 break; 00322 } 00323 00324 if (while_pri) 00325 ast_parseable_goto(chan, while_pri); 00326 00327 return 0; 00328 }
| 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().
00303 { 00304 return _while_exec(chan, data, 1); 00305 }
| 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().
00307 { 00308 return _while_exec(chan, data, 2); 00309 }
| 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().
00299 { 00300 return _while_exec(chan, data, 0); 00301 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .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.
1.6.2